Django модель, условно основанная на двух абстрактных классах
У меня скорее концептуальный вопрос, но с практическими последствиями.
В приложении Django 4.1.x у меня есть один класс owner
, который может быть либо person
, либо organization
, но никогда оба вместе.
Эти два класса не нужно регистрировать в базе данных, только owner
нужно:
from django.db import models
class Person(models.Model):
first_name = models.CharField(
max_length=256,
verbose_name=_("First name"),
null=False,
)
# other person attributes
class Meta:
abstract = True
def __str__(self):
return self.first_name
class Organization(models.Model):
full_name = models.CharField(
max_length=256,
verbose_name=_("Full name"),
null=False,
)
# other organization attributes
class Meta:
abstract = True
def __str__(self):
return self.full_name
Каким бы ни был экземпляр owner
, он должен иметь атрибут name
:
.
В случае человека, имя владельца должно быть first_name
, а в случае организации - full_name
.
Также, если объект owner
является экземпляром Person
: я хочу раскрывать только те другие атрибуты Person
. То же самое, если owner
является экземпляром Organization
.
Я, конечно, упускаю некоторые концепции здесь / может быть, я не смотрю в правильном направлении, но как построить owner
модель, основанную на типе "условного или параметризованного наследования", скажем?
Обратите внимание, что класс Person
также используется для построения других объектов, таких как, например, designer
или painter
во всем приложении. То же самое относится и к Organization
, который служит основой для различных типов организаций. Отсюда их abstract = True
.
Есть несколько возможных подходов, но они имеют свои недостатки. Многое зависит от того, насколько важно, чтобы все ваши классы использовали одну и ту же таблицу. Как правило, если неабстрактной модели нужны новые поля, ей нужна новая таблица.
Абстрактные классы:
Они полезны как архетипы, но вы не можете объединить их и затем иметь только один абстрактный класс "активным". Если Org и Person - оба абстрактных класса, используемые для создания Owner, то Owner будет иметь все поля обоих классов.
Любой не абстрактный класс будет нуждаться в собственной таблице, например, дети Owner или другие классы с абстракцией Person.
Прокси-классы:
Это, по сути, ваш вариант использования только одной таблицы. Используя этот метод, вы можете создать отдельные дочерние классы для вашего класса и его дочерних классов, используя одну и ту же таблицу, при этом каждый класс будет иметь свои методы и свойства. Однако все они должны использовать одни и те же поля. Если новые поля нужны только некоторым дочерним классам, их можно добавить в базовый класс без особых накладных расходов и обрабатывать или игнорировать с помощью методов соответствующего прокси-класса.