如何在Django中使用模型继承处理M2M关系的保存后信号?
问题的标题与句子完全相同,但希望下面的代码能够澄清这一点:如何在Django中使用模型继承处理M2M关系的保存后信号?,django,django-models,many-to-many,django-signals,Django,Django Models,Many To Many,Django Signals,问题的标题与句子完全相同,但希望下面的代码能够澄清这一点: class Foo(models.Model): ... class AbstractParent(models.Model): foos = models.ManyToManyField( Foo, related_name='%(app_label)s_%(class)s_related' ) def bar(self): ... cla
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
的基类对类Foo
有一个M2M。我想做的是:每当保存Foo
类的对象时,我想调用ClassOne
和ClassTwo
的所有对象的bar()
方法,该方法通过foos
字段与Foo
对象相关。为此,我试着写一个简单的信号:
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
类的所有子类并调用它们的bar()
方法?理想情况下,我只想查询我的数据库一次,在一次查询中,我想获得信号中与实例相关的ChildOne
和ChildTwo
的所有对象。请注意,在我的实际模型中,AbstractParent
有两个以上的子类,所以请给出一个记住这一点的答案。谢谢您的帮助。好吧,它不能满足您的单一查询要求,但这里有一种方法至少可以通过查询每个子类来完成这项工作:
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对象的唯一方法是通过select\u related
,这不适用于manytomy
关系
如果单个查询很重要,那么实现可能需要有关.bar()
的更具体的详细信息,这可能需要重构为一个类方法,该类方法可以处理.values()
调用或其他调用的结果。有没有办法在一个db查询中执行此查询?更新了更多详细信息,但简短的回答是:我还不够清楚。这是一个复杂的问题,这是我所知道的最好的实现。非常感谢。很抱歉再次提出此问题,但在测试代码后,我得到以下错误:TypeError:“ManyRelatedManager”对象不可编辑,在getattr(实例,字段.related\u名称)中的相关对象的行中:
抱歉,我取消了.all()
以使查询集可编辑。现在修好了。