Слабая связь приложений и образцовое наследование


keeplooping=True
while keeplooping:
    #Do Stuff
    while keeplooping:
          #do some other stuff
          if finisheddoingstuff(): keeplooping=False

или что-то как этот. Вы могли установить переменную во внутреннем цикле и проверить его во внешний цикл сразу после выходов внутреннего цикла, повредившись в подходящих случаях. Мне отчасти нравится метод GOTO, если Вы не возражаете использовать модуль Первоапрельской шутки - не Pythonic, но это действительно имеет смысл.

5
задан Nino 11 August 2009 в 10:40
поделиться

2 ответа

Я думаю, что вы ищете GenericForeignKey из фреймворка ContentTypes, который поставляется с Django в пакете contrib. Он обрабатывает запись типа и идентификатора экземпляра подкласса и обеспечивает простой способ доступа к подклассам в качестве свойства внешнего ключа модели.

В вашем случае это будет выглядеть примерно так:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Payment(models.Model):

    order_content_type = models.ForeignKey(ContentType)
    order_object_id = models.PositiveIntegerField()
    order = generic.GenericForeignKey('order_content_type', 'order_object_id')

Вы не делаете ' Чтобы использовать этот внешний ключ, не нужно делать ничего особенного ... настройка универсального дескриптора и прозрачное сохранение полей order_content_type и order_object_id :

s = SpecializedOrder()
p = Payment()
p.order = s
p.save()

Теперь, когда ваш Платеж метод сохранения запускается:

if is_paid:
    self.order.order_payment_complete()  # self.order will be SpecializedOrder
4
ответ дан 14 December 2019 в 19:20
поделиться

То, что вам нужно, называется динамическим полиморфизмом, и Django действительно плохо справляется с этим. (Я чувствую вашу боль)

Простейшее решение, которое я видел до сих пор, выглядит примерно так:

1) Создайте базовый класс для всех ваших моделей, которым нужна такая функция. Примерно так: (код явно украден из здесь )

class RelatedBase(models.Model):
    childclassname = models.CharField(max_length=20, editable=False)

    def save(self, *args, **kwargs):
        if not self.childclassname:
            self.childclassname = self.__class__.__name__.lower()
        super(RelatedBase, self).save(*args, **kwargs) 

    @property
    def rel_obj(self):
        return getattr(self, self.childclassname)

    class Meta:
        abstract = True

2) Наследуйте свой заказ от этого класса.

3) Когда вам понадобится объект Order, используйте его rel_obj атрибут, который вернет вам базовый объект.

Это решение далеко не изящное, но я еще не нашел лучшего ...

1
ответ дан 14 December 2019 в 19:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: