Может ли модель Django иметь два абстрактных класса? - PullRequest
3 голосов
/ 29 июня 2010

У меня есть эти модели:

class BillHeader(models.Model):
    billno = models.IntegerField(primary_key=True, blank=True)

class BillData(models.Model):
    price = models.DecimalField(_('Price'), max_digits=12, decimal_places=2)
    amount = models.DecimalField(_('Amount'), max_digits=6, decimal_places=2)

    [... rest of the model ...]

    class Meta:
        abstract = True

class BillFooter(models.Model):
    total = models.DecimalField(_('Total'), max_digits=12, decimal_places=2)

    [... rest of the model ...]

    class Meta:
        abstract = True

BillData и BillFooter являются общими для каждого BillHeader, поэтому я пометил их как abstract. Могу ли я сделать class BillHeader(BillData, BillFooter) или я делаю что-то не так?

Я также думал о том, чтобы сделать BillData основным, а BillHeader BillFooter абстрактным. У меня нет опыта работы с моделями данных (по крайней мере, не сложными), и я немного растерялся. Что бы вы порекомендовали?

1 Ответ

8 голосов
/ 30 июня 2010

Да, модель Django может наследовать от стольких абстрактных базовых классов, сколько пожелаете, если только они не приводят к неоднозначному «порядку разрешения модели».Думайте о наследовании как о цепочке ... каждый класс, от которого вы наследуете, является звеном в цепочке.Наследование от двух базовых классов - это просто добавление двух цепочек вместо одной.

Другими словами, если ваши абстрактные базовые классы наследуются от models.Model, то не пытайтесь наследовать обе абстрактные базы.класс и models.Model в вашем Bill классе.models.Model уже находится в цепочке наследования, поэтому наследование от него вызывает хаос в цепочке базовых классов.

Что касается того, как I будет структурировать эти классы, я бы создал модель под названиемBill, унаследованный от BillHeader, BillData и BillFooter.Причина этого в том, что мне нравятся мои модели Django для представления отдельных объектов (например, Bill, Article, BlogPost, Photo и т. Д.)

Однако смысл абстрактных базовых классов в том, чтобы иметь возможность добавлять уровеньабстракции для общих полей и методов, так что несколько классов могут наследовать от них.Если вы просто создаете класс Билла, это несколько бессмысленно.Однако, если у вас есть Билл, UnpaidBill и PaidBill ... у всех них есть общие поля, которые должны отображаться на всех них, и вы можете избавить себя от множества проблем, абстрагировавшись в азбуку.

Надеюсь, это поможет немного понять, для чего нужны ABC и наследование.

...