Hom*_*lli 8 python django django-models
我正在使用 Django 4.0
我有以下型号:
class Parent(models.Model):
# fields ommitted for the sake of brevity
pass
class Child(Parent):
child_only_field = models.CharField(max_length=64)
Run Code Online (Sandbox Code Playgroud)
p = Parent.objects.create(**fields_dict)
c1 = Child.objects.create(child_only_field='Hello 123', p) # Obviously won't work
# c2 = ...
Run Code Online (Sandbox Code Playgroud)
有没有办法从父对象的实例创建子对象(无需手动“解包”父对象的字段)?
小智 5
如果您了解 Django 如何使用 implizit o2o 关系,这很容易。
class Parent(Model):
# fields
# implizit o2o
class Child(Parent):
child_only_field = models.CharField(max_length=64)
# explizit o2o
class Child_1(Parent):
parent = models.OneToOneField(Parent)
child_only_field = models.CharField(max_length=64)
Run Code Online (Sandbox Code Playgroud)
1.通过现有的父类对象保存子对象,不要在正常代码中使用它。
parent = Parent.objects.get(pk=some_pk)
child = Child(child_only_field='Hello 123', pk=parent.pk)
child.save_base(raw=True) # important part of code
Run Code Online (Sandbox Code Playgroud)
Model.save_base
- 仅保存子字段信息的内部方法。但父数据应该已经存在。
2.将创建的父级保存为子级。不要在正常代码中使用它:
parent = Parent.objects.get(pk=some_pk)
parent.child_only_field = 'Hello 123'
parent.save_base(class=Child)
Run Code Online (Sandbox Code Playgroud)
Model.save_base
方法保存整个继承链的信息。
3.正常保存创建的子进程。请在正常代码中使用它:
child = Child(child_only_field='Hello 123', **fields_dict)
child.save()
Run Code Online (Sandbox Code Playgroud)
我特别不使用 DataManager。我可以说,这更多的是内部方法,而不是公共接口。
通过 DataManager 保存子项。
child = Child.objects.create(child_only_field='你好123', **fields_dict)
objects.create
从我的回答中得出了第3点。你可以在 django.db.models.query.py 中看到它
我希望它有帮助。
通过和将 的字段转换p
为字典。model_to_dict
p._meta.fields
from django.forms.models import model_to_dict
class Parent(models.Model):
# fields ommitted for the sake of brevity
def fields_dict(self):
return model_to_dict(
p,
fields=[
field.name
for field in self._meta.fields
if field.name in self.__dict__
and field.name != self._meta.pk.name
]
)
class Child(Parent):
child_only_field = models.CharField(max_length=64)
p = Parent.objects.create(**fields_dict)
c1 = Child.objects.create(child_only_field='Hello 123', **p.fields_dict())
Run Code Online (Sandbox Code Playgroud)
也可以覆盖create
方法。
from django.forms.models import model_to_dict
class MyManager(models.Manager):
def create(self, *args, **kwargs):
if 'parent_obj' in kwargs:
parent_fields = parent_obj.fields_dict()
return super().create(*args, **kwargs, **parent_fields)
class Parent(models.Model):
# fields ommitted for the sake of brevity
def fields_dict(self):
return model_to_dict(
p,
fields=[
field.name
for field in self._meta.fields
if field.name in self.__dict__
and field.name != self._meta.pk.name
]
)
class Child(Parent):
objects = MyManager()
child_only_field = models.CharField(max_length=64)
p = Parent.objects.create(**fields_dict)
c1 = Child.objects.create(child_only_field='Hello 123', parent_obj=p)
Run Code Online (Sandbox Code Playgroud)