【发布时间】:2016-01-01 07:12:37
【问题描述】:
我花了很多时间来寻找一个我认为应该是 Django 中相当基本的功能的功能。但我就是无法让它工作,或者用 Django 是不可能的——这将是非常令人失望的......
好的,我有两个模型,假设一个 Contact 和一个 Address 模型。一个联系人可以有多个地址,一个地址可能属于多个联系人。经典的多对多关系。
class Contact(models.Model):
... (some other attributes)
addresses = models.ManyToManyField(Address)
class Address(models.Model):
... (some attributes)
contact = models.ForeignKey(Contact) # <- needed for inline formset
我有一个联系人模型的表单,并在其中包含了一个用于地址的内联表单集。这个想法是我在联系人表单中有一个地址多选小部件(从已保存的地址中选择)并通过内联表单集动态添加新地址。
但是,通过内联表单集添加地址会保存地址实例,但不会保存直通表中的条目来标记联系人与新保存的地址之间的关系。这也意味着在使用 EditView 查看 Contact 实例时,不会在 MultiSelect 字段中选择这个新保存的地址。
我在保存地址和联系人实例时使用save(commit=False),因为我需要在保存之前添加其他数据。我知道你必须以某种方式使用save_m2m(),但它不起作用。
顺便说一下,Address 模型与 Contact 模型有外键关系,否则我无法使用内联表单集。
当表单有效且即将保存时我的一些视图代码:
self.object = form.save(commit=False)
self.object.someAttribute = theAttributeValue # just adding some attribute
self.object.save()
# In case there is a many-to-many relationship to another model, we need to use the save_m2m() method
form.save_m2m()
for formset in formsets:
formset.instance = self.object
saved_formset = formset.save(commit=False)
"""
If you call formset.save(commit=False), objects will not be deleted automatically. You’ll need to call
delete() on each of the formset.deleted_objects to actually delete them. See also: https://docs.djangoproject.com/en/1.8/topics/forms/formsets/#django.forms.formsets.BaseFormSet.can_delete
"""
for obj in formset.deleted_objects:
obj.delete()
for form in saved_formset:
form.someAttribute = theAttributeValue
form.save()
formset.save_m2m()
请帮帮我,这太疯狂了。一定有办法让这项工作,对吧?我没看到什么?
【问题讨论】:
-
“顺便说一下,地址模型与联系人模型有外键关系,否则我无法使用内联表单集” - 这是否意味着您在
Contact之间有两种关系和Address(在Contact模型中指定的ManyToMany 和Address模型中的ForeignKey)? -
没错。这没有多大意义,但是 - 正如我所说 - 否则我在查看创建/更新表单时收到 Django 错误,指出地址模型需要联系人模型的外键。我刚刚更新了上面的模型描述。
-
现在在重置我的迁移(需要)并尝试进行初始迁移(使用现有表)之后,我在循环依赖 Django 错误中再次运行:django.db.migrations.graph.CircularDependencyError: address.0001_initial,contacts.0001_initial 我以前有过这个,不知怎的,当我发布我的问题时,我让它工作了。但总的来说,拥有 ForeignKey ManyToMany 关系似乎不起作用。但是,我仍然无法相信 Django 无法实现图示的用例,它对我来说只是一个基本功能。解决办法是什么?
标签: django formset inline-formset m2m