Django模型形式在实例之后节省了m2m

2024-05-04 05:19:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我对基于Django类的表单保存表单的方式有一个问题。我正在为我的一个模型使用form.ModelForm,它有一些多对多的关系。在

在模型的save方法中,我检查其中一些关系的值以修改其他属性:

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(),它以一种形式保存多对多关系。在

事情是这样的,请查看save_instance在保存时选择的顺序以及instance和m2m:

^{pr2}$

显然问题就在这里。首先调用实例的save方法,这就是为什么self.m2m_relationship是空的QuerySet。只是还不存在。在

我能做些什么?我不能仅仅改变save_instance函数中的顺序,因为它是Django的一部分,我可能会破坏其他东西。在


Tags: django方法instance函数模型selfform表单
2条回答

丹尼尔的回答给出了这种行为的原因,你无法纠正它。在

但是当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相关的类的实例”。在

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

但是用其他方法是不可能的。在

多对多关系不是实例上的字段,而是链接表中的一个条目。在实例本身存在之前,不可能保存该关系,因为它没有ID进入链接表。在

相关问题 更多 >