我对Django基于类的表单保存表单的方式存在问题。我正在使用form.ModelForm
作为我的一个模型,它具有多对多的关系。
在模型的保存方法中,我检查其中一些关系的值以修改其他属性:
class MyModel(models.Model):
def save(self, *args, **kwargs):
if self.m2m_relationship.exists():
self.some_attribute = False
super(MyModel, self).save(*args, **kwargs)
即使我在我的表单中填充m2m关系中的一些数据,我在保存模型时self.m2m_relationship
,但令人惊讶的是它是空的QuerySet
。我最终发现了以下内容:
调用form.save()
方法来保存表单,它属于BaseModelForm
类。然后,此方法返回save_instance
forms\models.py
中的函数。此函数定义了一个本地函数save_m2m()
,它可以在表单中保存多对多关系。
在这里,检查保存和实例和m2m时选择的save_instance
订单:
instance.save()
save_m2m()
显然问题出在这里。首先调用实例的save
方法,这就是self.m2m_relationship
为空QuerySet
的原因。它还没有存在。
我该怎么办?我不能只改变save_instance
函数中的顺序,因为它是Django的一部分,我可能会破坏别的东西。
答案 0 :(得分:2)
但是不可能以任何其他方式去做。
多对多关系不是实例上的字段,它是链接表中的条目。在实例本身存在之前,没有可能的方法来保存该关系,因为它不会有一个ID进入该链接表。
答案 1 :(得分:2)
Daniel的答案给出了这种行为的原因,你将无法修复它。
但是只要有关m2m关系发生变化就会发送m2m_changed
信号,也许你可以使用它:
from django.db.models import signals
@signals.receiver(signals.m2m_changed, sender=MyModel.m2m_relationship.through)
def handle_m2m_changed(sender, instance, action, **kwargs):
if action == 'post_add':
# Do your check here
但请注意docs表示实例“可以是发件人的实例,也可以是ManyToManyField与之相关的类的实例。”
我不知道它是如何工作的,但你可以试试你得到的,然后调整代码。