我花了很多时间寻找一个我认为应该是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
我有一个Contact模型的表单,其中包含一个Addresses的内联formset。我的想法是,我在联系表单中有一个Addresses MultiSelect小部件(从已保存的地址中选择),并通过内联formset动态添加新的地址。
但是,通过内联formset添加地址将保存地址实例,但不会保存直通表中的条目以标记联系人与新保存的地址之间的关系。这也意味着在使用EditView查看Contact实例时,MultiSelect字段中未选中此新保存的地址。
我在保存Address和Contact实例时使用save(commit=False)
,因为我需要在保存之前添加其他数据。我知道你必须以某种方式使用save_m2m()
,但它不起作用。
顺便说一下,Address模型与Contact模型有外键关系,否则我无法使用内联formset。
当表单有效且即将保存时,我的一些代码:
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()
请帮帮我,这只是变得疯狂。必须有办法让这项工作,对吗?我没看到什么?
答案 0 :(得分:1)
要管理您的循环相关性,我建议您从以下地址切换:
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
为:
class Contact(models.Model):
... (some other attributes)
addresses = models.ManyToManyField('myapp.Address')
class Address(models.Model):
... (some attributes)
contact = models.ForeignKey('myapp.Contact') # <- needed for inline formset
你是否看到我如何定义关系的区别?我传入模型类的'字符串映射',而不是传入模型类。然后Django处理剩下的事情。
此应该处理您的循环依赖问题。并且可能解决formsets
带来的任何故障。但是,由于我倾向于远离formsets
,我无法肯定地说。