Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Django模型表单在实例后保存m2m_Python_Django_Python 2.7_Django 1.4 - Fatal编程技术网

Python Django模型表单在实例后保存m2m

Python Django模型表单在实例后保存m2m,python,django,python-2.7,django-1.4,Python,Django,Python 2.7,Django 1.4,我对基于Django类的表单保存表单的方式有疑问。我正在使用表单。ModelForm作为我的一个模型,它具有一些多对多关系 在模型的保存方法中,我检查其中一些关系的值以修改其他属性: class MyModel(models.Model): def save(self, *args, **kwargs): if self.m2m_relationship.exists(): self.some_attribute = False super(MyModel, se

我对基于Django类的表单保存表单的方式有疑问。我正在使用
表单。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\u关系
,令人惊讶的是,它是一个空的
QuerySet
。我最终发现了以下几点:

调用
form.save()
方法来保存表单,它属于
BaseModelForm
类。然后此方法返回
save\u instance
,这是
forms\models.py
中的一个函数。此函数定义一个本地函数
save_m2m()
,该函数将多对多关系保存在一个表单中

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

instance.save()
save_m2m()
显然,问题就在这里。首先调用实例的
save
方法,这就是为什么
self.m2m\u关系
是空的
QuerySet
。它只是还不存在


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

但用任何其他方法都不可能做到


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

但不可能以任何其他方式进行保存


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

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
但请注意,假设实例“可以是发送方的实例,也可以是ManyToManyField相关的类的实例”


我不知道这到底是怎么回事,但你可以试试你得到的,然后修改代码。

丹尼尔的回答给出了这种行为的原因,你将无法修复它

但每当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
但请注意,假设实例“可以是发送方的实例,也可以是ManyToManyField相关的类的实例”


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

那么我能做什么呢?一些基于m2m的后期保存操作来修改我想要的内容?那么我能做什么呢?一些基于m2m的后期保存操作来修改我想要的内容?因此文档所说的基本上是,如果
MyModel
和它相关的模型实例在现有关联中进行更改时都会触发信号?是的,中间有一个不可见的表,即MyModel.m2m\u relationship.through,如果这种情况发生变化,那么不管发生了什么,信号都会被发送。但我不知道发送了哪个实例,你需要尝试一下。是的,这真的不重要,因为只有
MyModel
才是更改它的人。如果是另一个,我想我还是会用m2m改变动作。应该是接收器,但是。通过应该工作。好吧,我的IDE有一个荒谬的错误。它坚持它应该是
虽然
而不是
通过
…因此,doc所说的基本上是,如果
MyModel
和它所关联的模型的一个实例在现有关联中进行更改时,信号将被触发?是的,中间有一个不可见的表,即MyModel.m2m_relationship.through,如果该表发生变化,则会发送信号,而不管发生了什么。但我不知道发送了哪个实例,你需要尝试一下。是的,这真的不重要,因为只有
MyModel
才是更改它的人。如果是另一个,我想我还是会用m2m改变动作。应该是接收器,但是。通过应该工作。好吧,我的IDE有一个荒谬的错误。它坚持认为应该是
尽管
,而不是
通过
。。。