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.

Прокси-классы:

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

Вернуться на верх