Поток создания объекта управления в Django моделях наследования - PullRequest
2 голосов
/ 15 апреля 2020

Я прочитал Django документ о моделях наследования и parent_link. Предположим, у меня есть следующие модели:

class Parent(models.Model):
    #Some field goes here! 
class Child(Parent):
    #Some field goes here! 

У меня есть 3 вопроса об этом шаблоне:

  1. Что мне делать, если я хочу создать новый дочерний объект и передать идентификатор существующего родителя для этого?

  2. Что мне делать, если я хочу создать только новый дочерний объект и через некоторое время создать родительский объект для этого дочернего объекта?

  3. Также я не понимаю этот документ о parent_link:

    OneToOneField.parent_link

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

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

Обновление вопроса Предположим, эти модели:

class User(AbsteractBaseUser):
    #Some field goes here! 

class Student(User):
    #Some field goes here! 

class Teacher(User):
    #Some field goes here! 

class Employee(User):
    #Some field goes here! 
Можно ли создать Teacher объект и поставить pk существующего User объекта для этого учителя?

Ответы [ 2 ]

3 голосов
/ 15 апреля 2020

Для моделей Django существует два типа наследования: абстрактное и конкретное.

В первом случае нет ни таблицы для абстрактного базового класса, ни «родительской записи», каждая дочерняя модель имеет собственную полную таблицу со всеми полями (унаследованными и принадлежащими). ​​

В Во втором случае (также известном как «наследование нескольких таблиц») есть одна таблица для родительской модели с полями родительской модели и одна таблица для каждой дочерней модели с полем OneToOne (технически FK) в родительской таблице и дочерней модели. собственные поля. Вы можете NOT"управлять созданием" родительской записи при создании дочерней записи или создавать дочернюю запись без родительской записи (требуется fk).

You может (по крайней мере, технически) создать родительскую запись без дочернего элемента, а затем создать дочерний элемент и связать его с родителем (что на самом деле Django делает под капотом, когда вы создаете дочернюю запись с момента дочерней записи). требует фк к родителю) но это ИМХО сильный запах дизайна - если для вашего приложения имеет смысл иметь родительскую запись без потомка, вероятно, вам вообще не следует использовать наследование (вы можете использовать поля OneToOne без наследования).

по отношению к OneToOneField.parent_link: когда вы используете конкретное наследование и явно не предоставляете поле OneToOne для родительской модели Django создаст его для вас (точно так же, как это создает поле первичного ключа, если вы явно не определяете его). Если вы хотите явно определить поле OneToOne для своей родительской модели в дочерней модели, вы должны указать Django, что это поле OneToOne является ссылкой на родительский объект и что 'для чего этот флаг.

Последнее замечание: по опыту наследование нескольких таблиц (независимо от того, какой у вас уровень доступа к данным - django orm, slqalchemy, обычное руководство SQL et c) всегда немного PITA, поэтому используйте его только где это действительно имеет смысл.

2 голосов
/ 15 апреля 2020

Вы не можете сделать это в Django ORM. Потому что, если вы думаете о базе данных, это возможно, но в OOP это невозможно. Поэтому не следует использовать наследование модели в Django ORM. Когда вы используете наследование, внешний ключ родительского объекта создается в дочернем объекте в базе данных, но вы не можете им управлять. Вы не можете изменить или установить его во время создания. Если вы видите с точки зрения базы данных, когда вы создаете дочерний объект, в базе данных создаются два объекта, то есть один в родительском и один в дочернем. Вы должны иметь возможность назначить другого родителя этому дочернему объекту. Но когда вы видите OOP точку зрения, согласно OOP принципам, когда создается дочерний объект, он наследует все свойства родительского элемента и создается только один объект. Так что не имейте свободы назначать другой родительский объект этому ребенку.

Вместо этого вы можете использовать абстрактные модели. Если вы не можете удалить наследование, вы можете сделать это с помощью RAW SQL. В противном случае никакой другой опции не будет.

Если вы можете удалить наследование, создайте OnetoOneField у дочернего элемента с родителем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...