Django模型形式在实例后保存m2m
Django model form saves m2m after instance
我对基于 Django class 的表单保存表单的方式有疑问。我正在为我的一个模型使用 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
class。那么这个方法returnssave_instance
,forms\models.py
中的一个函数。该函数定义了一个局部函数save_m2m()
,它以一种形式保存多对多关系。
事情是这样的,检查 save_instance
在保存和实例以及 m2m 时选择的顺序:
instance.save()
save_m2m()
显然问题就在这里。实例的 save
方法首先被调用,这就是为什么 self.m2m_relationship
是一个空的 QuerySet
。它只是还不存在。
我该怎么办?我不能只更改 save_instance
函数中的顺序,因为它是 Django 的一部分,我可能会破坏其他东西。
但用其他方式是不可能的。
many-to-many 关系不是实例上的字段,它是链接 table 中的条目。在实例本身存在之前无法保存该关系,因为它没有进入该链接的 ID table.
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 表示实例 "can be an instance of the sender, or of the class the ManyToManyField is related to"。
我不知道它到底是如何工作的,但你可以尝试一下你得到的,然后调整代码。
我对基于 Django class 的表单保存表单的方式有疑问。我正在为我的一个模型使用 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
class。那么这个方法returnssave_instance
,forms\models.py
中的一个函数。该函数定义了一个局部函数save_m2m()
,它以一种形式保存多对多关系。
事情是这样的,检查 save_instance
在保存和实例以及 m2m 时选择的顺序:
instance.save()
save_m2m()
显然问题就在这里。实例的 save
方法首先被调用,这就是为什么 self.m2m_relationship
是一个空的 QuerySet
。它只是还不存在。
我该怎么办?我不能只更改 save_instance
函数中的顺序,因为它是 Django 的一部分,我可能会破坏其他东西。
但用其他方式是不可能的。
many-to-many 关系不是实例上的字段,它是链接 table 中的条目。在实例本身存在之前无法保存该关系,因为它没有进入该链接的 ID table.
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 表示实例 "can be an instance of the sender, or of the class the ManyToManyField is related to"。
我不知道它到底是如何工作的,但你可以尝试一下你得到的,然后调整代码。