Control object creation flow in Django inheritance models

大憨熊 提交于 2020-05-15 07:19:45

问题


I have been read some Django document about inheritance models and parent_link. Suppose that I have these models:

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

I have 3 questions about this pattern:

  1. What should I do if I want to create new child object and pass id of existing parent to that?

  2. What should I do if I want to create just new child object and after a while create parent object for that child?

  3. Also I din't understand this document about parent_link:

    OneToOneField.parent_link

    When True and used in a model which inherits from another concrete model, indicates that this field should be used as the link back to the parent class, rather than the extra OneToOneField which would normally be implicitly created by subclassing.

Thanks for your help!

Update Question Suppose these models:

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! 
  1. Is it possible to create Teacher object and put the pk of existing User object for that teacher?

回答1:


You cannot do that in Django ORM. Because if you think of database, it is possible but in OOP, it is not possible. So you should not use model inheritance in Django ORM. When you use inheritance, a foreign key to parent is created in child object in database but you cannot control it. You cannot change it or set it at the time of creation. If you see from database point of view, when you create child object, two objects are created in database i.e. one in parent and one in child. You should be able to assign another parent to this child object. But when you see OOP point of view, according to OOP principles, when a child is created, it inherits all the properties of parent and only one object is created. So do not have freedom to assign another parent object to this child.

You can use abstract models instead. If you cannot remove inheritance, then you can do it with RAW SQL. Otherwise there is no any other option.

If you can remove inheritance, create a OnetoOneField in child with parent.




回答2:


There are two types of inheritance for Django models: abstract and concrete.

In the first case, there's no table for the abstract base class nor "parent record", each child model has it's own full table with all fields (inherited and owned).

In the second case (also known as "multi-table inheritence", there's one table for the parent model with the parent model's fields, and one table for each child model with a OneToOne field (technically a FK) on the parent table and the child model's own fields. You can NOT "control creation" of the parent record when creating a child record nor create a child record without it's parent record (the fk is required).

You could (technically at least) create a parent record without child and then create the child and link it to the parent (which is actually what Django is doing under the hood when you create a child record since the child record requires the fk to the parent) but it's IMHO a strong design smell - if it makes sense for your app to have a parent record without child then you probably shouldn't be using inheritance at all (you can use OneToOne fields without inheritance).

wrt/ the OneToOneField.parent_link : when you use concrete inheritance and don't explicitely provide a OneToOne field to the parent model, Django will create it for you (just like it creates a primary key field if you don't explicitely define one). If you want to explicitely define the OneToOne field to your parent model in the child model, you have to tell Django that this OneToOne field IS the link to the parent, and that' what this flag is for.

As a last note: from experience, multi-table inheritance (whatever your data access layer is - django orm, slqalchemy, plain manual SQL etc) is always a bit of a PITA, so only use it where it really makes sense.



来源:https://stackoverflow.com/questions/61223580/control-object-creation-flow-in-django-inheritance-models

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!