Наследование модели или внешний ключ?

Я уверен, что, вероятно, есть несколько способов сделать то, что я достигаю, но столкнулся с некоторыми проблемами. У меня есть модель «член», и я также пытаюсь добавить «зависимую» модель, которая наследует некоторые поля и данные от родителя (члена), но также имеет некоторые из тех же полей, но свои собственные данные. Как лучше всего этого добиться? ForeignKey, OneToOne или ManyToMany, или это вообще возможно?

Пример:

class Member(models.Model):
    name = models.CharField(max_length=128)
    address = models.CharField(max_length=128)
    age = models.DateField()

class Dependent(models.Model):
    name = models.CharField(max_length=128) (different name)
    address = models.CharField(max_length=128) (same address as Member)
    age = models.DateField() (different age)

Спасибо за помощь.

Разве флаг is_dependent здесь не должен быть лучшим вариантом? Итак, BooleanField, который указывает, является ли он зависимым. Кроме того, 1-1, m2m и ForeignKey имеют разные кванторы, так что это не вопрос «дизайна», а фундаментальное различие в моделировании.

Willem Van Onsem 10.09.2018 10:59

ForeignKey кажется лучшей идеей, потому что наследование здесь не имеет особого смысла, и это, вероятно, не отношение один к одному или многие ко многим.

gagan trivedi 10.09.2018 11:02

С другой стороны, если Member может иметь ноль, один или несколько Dependent, ForeignKey будет моделировать отношение «многие к одному». Вы также можете использовать модель Аннотация, которая содержит общие поля.

Willem Van Onsem 10.09.2018 11:03

Но вышеизложенное неясно, поэтому я думаю, вам следует предоставить дополнительную информацию: как Dependent соотносится с Member? Может ли участник иметь ноль, один или несколько Dependent? Может ли Dependent содержать ноль, один или несколько Member? Является в Dependent в Member?

Willem Van Onsem 10.09.2018 11:04

Вам действительно следует сделать семантическую связь между Member и Dependant более ясной, как этого требует @WillemVanOnsem. В противном случае на этот вопрос нельзя будет ответить должным образом.

schwobaseggl 10.09.2018 11:46

Спасибо вам всем за ответы. У члена может быть ноль, один или несколько иждивенцев. Иждивенца нужно привязать к члену. Я буду добавлять форму для самого члена, чтобы добавить иждивенца. поле "member_number" будет таким же, но с добавлением -1, -2 или -3 и т. д.

K. Jones 10.09.2018 18:03
1
6
336
1

Ответы 1

Поскольку Dependent имеет те же поля, что и Member, но имеет несколько дополнительных полей, вы можете заставить и Dependent, и Member наследовать абстрактный базовый класс (спасибо @WillemVanOnsem за указание на это), чтобы избежать переопределения тех же полей, и поскольку Member и Dependent имеют родительский - дочерние отношения, вы должны добавить внешний ключ к Member в качестве дополнительного поля в модели Dependent. Вы также можете переопределить метод save для Member, чтобы он синхронизировал адреса своих дочерних Dependent при сохранении.

class Person(models.Model):
    name = models.CharField(max_length=128)
    address = models.CharField(max_length=128)
    age = models.DateField()

    class Meta:
        abstract = True

class Member(Person):
    def save(self):
        super().save()
        self.dependents.exclude(address=self.address).update(address=self.address)

class Dependent(Person):
    parent = models.ForeignKey(Member, related_name='dependents')
    extra_field = ...

Но, унаследовав неабстрактную модель, у вас уже есть «неявное» отношение parent, за исключением того, что это скорее отношение OneToOneField. См .: godjango.com/blog/…

Willem Van Onsem 10.09.2018 11:23

Неявный родитель здесь на самом деле не родитель, а просто базовая личность наследника. Внешний ключ по-прежнему необходим для обозначения реальных родительско-дочерних отношений.

blhsing 10.09.2018 11:26

@bihsing: а где в вопросе вы читаете про многие-к-одному. Здесь отношение родитель-потомок может относиться к двум вещам: (а) наследованию или (б) тому факту, что Dependent имеет отношение «многие к одному» к Member. Кроме того, при использовании такого наследования нам потребуются дополнительные JOIN для выборки данных. Хотя наследование предусмотрено в Django, обычно это не очень хорошая практика.

Willem Van Onsem 10.09.2018 11:28

Действительно. Я просто сделал вывод об отношении «многие к одному» по значению слова «зависимый» (и что он должен иметь тот же адрес, что и родительский). Для меня это имеет смысл с точки зрения вероятного использования в реальном мире.

blhsing 10.09.2018 11:31

Хороший аргумент в пользу неотъемлемого недостатка наследования неабстрактной модели. Я обновил свой ответ, чтобы вместо этого использовать абстрактный базовый класс. Спасибо, что указали на это.

blhsing 10.09.2018 11:43

Другие вопросы по теме