Полиморфное (на основе полученной модели) наследование модели в Django - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть следующая структура наследования моих моделей Django:

  • Transaction
    • SimpleTransaction
    • SubscriptionTransaction
  • Item
    • SimpleItem
    • SubscriptionItem

Модель SimpleTransaction относится к модели SimpleItem, а класс SubscriptionTransaction относится к модели SubscriptionItem.

Самый очевидный способ сделать это - определить поле item в Transaction:

class Transaction(models.Model):
    # ...
    item = models.ForeignKey('Item')
    # ...

Но я бы хотел, чтобы t.item ссылался на SimpleItem или SubscriptionItem (а не на базовый класс Item, как в приведенном выше коде) в зависимости от того, является ли t SimpleTransaction или SubscriptionTransaction.

Как это можно сделать в Джанго?

Или, может быть, ссылка на производный класс (SimpleItem или SubscriptionItem) вместо Item может как-то сильно повлиять на производительность, так как он будет запрашивать чтение SimpleItem или SubscriptionItem, даже когда просто Item поля необходимы? а так лучше обратиться к базовому классу, а не выдумывать такой вопрос? Однако наличие ссылок на определенный класс Item (не просто Item базовый класс) из SimpleTransaction или SubscriptionTransaction обеспечивает ссылочную целостность. Так я должен сделать это, чтобы улучшить «стабильность» БД?

1 Ответ

0 голосов
/ 16 сентября 2018

Альтернативное решение будет иметь отдельные item для "простых" и "подписных" классов:

class SimpleTransaction(models.Model):
    # ...
    item = models.ForeignKey('SimpleItem')
    # ...
# ...

class SubscriptionTransaction(models.Model):
    # ...
    item = models.ForeignKey('SubscriptionItem')
    # ...

Но в этом случае не было бы прямого способа (без использования условного оператора или подобного) ссылаться на связанную транзакцию из элемента:

i.simpletransaction if i.simpletransaction else i.subscriptiontransaction

Так что я исключаю этот способ как неприемлемый.

Возможно добавить эти свойства, однако:

class SimpleTransaction(Transaction):
    @property
    def simple_item(self):
        return self.item.simpleitem

class SubscriptionTransaction(Transaction):
    @property
    def subscription_item(self):
        return self.item.subscriptionitem

Я не вижу других способов решения этой проблемы.

...