如何在 Django 中处理具有模型继承的 M2M 关系的 post-save 信号?
How to handle a post-save signal for an M2M relationship with model inheritance in Django?
问题的标题很完整,但希望下面的代码能把它弄清楚:
class Foo(models.Model):
...
class AbstractParent(models.Model):
foos = models.ManyToManyField(
Foo,
related_name='%(app_label)s_%(class)s_related'
)
def bar(self):
...
class Meta:
abstract = True
class ChildOne(AbstractParent):
...
class ChildTwo(AbstractParent):
...
假设我的应用程序标签是 'myapp'。
基本上,ChildOne
和 ChildTwo
的基数 class 有一个 M2M 到 class Foo
。我想做的是:每当保存 Foo
class 的 object 时,我想调用所有 object 的 bar()
方法ClassOne
和 ClassTwo
通过 foos
字段与 Foo
object 相关。为此,我尝试编写一个简单的信号:
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Foo)
def call_bar_for_all_related_objects_to_foo(sender, instance, **kwargs):
# Do the thing
在这一点上,我有点迷路了。如何查询 AbstractParent
class 的所有 children classes 并在与 [=24= 有关系时调用它们的 bar()
方法] 在信号?理想情况下,我只想查询我的数据库一次,并且在一次查询中,我想获取与 instance
中的 instance
相关的 ChildOne
和 ChildTwo
的所有 object信号。请注意,在我的实际模型中,AbstractParent
有两个以上的 child class,因此请记住这一点的答案表示赞赏。感谢您的帮助。
好吧,它不能满足您的单一查询要求,但这里有一种方法至少可以通过每个 child class:
的查询来完成工作
def call_bar_for_all_related_objects_to_foo(sender, instance, **kwargs):
for field in instance._meta.get_fields():
if not field.related_model:
continue
if not issubclass(field.related_model, AbstractParent):
continue
for related_object in getattr(instance, field.related_name).all():
related_object.bar()
单个查询更新
我不认为这可以通过像这样的一般方式在单个查询中完成。我知道从单个查询中获取整个相关的 django objects 的唯一方法是通过 select_related
,它不适用于 ManyToMany
关系。
如果单个查询很重要,实施可能需要关于 .bar()
的更具体细节,这可能需要重构为 class 方法,该方法适用于 .values()
打电话什么的。
问题的标题很完整,但希望下面的代码能把它弄清楚:
class Foo(models.Model):
...
class AbstractParent(models.Model):
foos = models.ManyToManyField(
Foo,
related_name='%(app_label)s_%(class)s_related'
)
def bar(self):
...
class Meta:
abstract = True
class ChildOne(AbstractParent):
...
class ChildTwo(AbstractParent):
...
假设我的应用程序标签是 'myapp'。
基本上,ChildOne
和 ChildTwo
的基数 class 有一个 M2M 到 class Foo
。我想做的是:每当保存 Foo
class 的 object 时,我想调用所有 object 的 bar()
方法ClassOne
和 ClassTwo
通过 foos
字段与 Foo
object 相关。为此,我尝试编写一个简单的信号:
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=Foo)
def call_bar_for_all_related_objects_to_foo(sender, instance, **kwargs):
# Do the thing
在这一点上,我有点迷路了。如何查询 AbstractParent
class 的所有 children classes 并在与 [=24= 有关系时调用它们的 bar()
方法] 在信号?理想情况下,我只想查询我的数据库一次,并且在一次查询中,我想获取与 instance
中的 instance
相关的 ChildOne
和 ChildTwo
的所有 object信号。请注意,在我的实际模型中,AbstractParent
有两个以上的 child class,因此请记住这一点的答案表示赞赏。感谢您的帮助。
好吧,它不能满足您的单一查询要求,但这里有一种方法至少可以通过每个 child class:
的查询来完成工作def call_bar_for_all_related_objects_to_foo(sender, instance, **kwargs):
for field in instance._meta.get_fields():
if not field.related_model:
continue
if not issubclass(field.related_model, AbstractParent):
continue
for related_object in getattr(instance, field.related_name).all():
related_object.bar()
单个查询更新
我不认为这可以通过像这样的一般方式在单个查询中完成。我知道从单个查询中获取整个相关的 django objects 的唯一方法是通过 select_related
,它不适用于 ManyToMany
关系。
如果单个查询很重要,实施可能需要关于 .bar()
的更具体细节,这可能需要重构为 class 方法,该方法适用于 .values()
打电话什么的。