Django模型表格在实例后节省了m2m

时间:2017-01-13 11:11:36

标签: python django python-2.7 django-1.4

我对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的一部分,我可能会破坏别的东西。

2 个答案:

答案 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与之相关的类的实例。”

我不知道它是如何工作的,但你可以试试你得到的,然后调整代码。