我有一个管理表单,其中包含几个用于显示m2m字段的内联,如下所示:

class ArticleAdmin(admin.ModelAdmin):
    form = ArticleCustomAdminForm
    inlines = (SpecificGemInline, SuiteInline,)


基类看起来像这样:

class Article(models.Model):
    article_code = models.CharField(max_length=15)
    gems = models.ManyToManyField(Gem, through='SpecificGem')


模型有一个特殊的字段article_code,该字段应聚合以两个内联表示的m2m字段中的一些数据,因此我编写了一个函数create_code(instance),该函数通过直接访问模型实例字段来实现,如下所示:

def create_code(instance):
    article_code_part1 = SpecificGem.objects.filter(article=instance)
    article_code_part2 = instance.suite_set.all()
    instance.article_code = #do something with both parts


问题是,当我从重写的ModelAdmin的save_model()或模型的save()函数调用此函数时,以下实例m2m字段会产生过时的结果。即使是以下示例,也无济于事:

class ArticleAdmin(admin.ModelAdmin):
    #...
    def save_model(self, request, obj, form, change):
        obj.save()
        create_code(obj)
        obj.save()


当我进入InlineFormset的clean()方法时,我可以访问其表单的数据,因此即使没有实际保存,我也可以找出article_code的一部分...但是我有两个内联函数。

那么,如何找到最顶层的save方法,以便在所有模型都经过验证并保存到db后调用聚合函数?

最佳答案

为了捕获对ManyToManyField的更改,您需要连接m2m_changed信号。您可能希望通常阅读signals的文档,尤其是m2m_changed signal的文档。

10-08 09:46