【问题标题】:Implementing a post-save logic by overriding save_related in Django Admin通过在 Django Admin 中覆盖 save_related 来实现保存后逻辑
【发布时间】:2025-12-01 06:25:01
【问题描述】:

有一些相关的帖子,但实际上没有一个是针对这个问题的。

我正在尝试在我的嵌套 Django 管理表单之一中实现保存后逻辑。嵌套我的意思是有内联。我已经能够通过像这样覆盖save_model 来实现逻辑,

def save_model(self, request, obj, form, change):
    #Added logic here using obj
    return super(SomeModelAdmin, self).save_model(request, obj, form, change)

显然,如果在其中一个内联中进行了更改,我的逻辑不会考虑它,因为save_model 仅应用于父对象。我在这个问题上找到了一个 Django ticket。它建议应该改用save_related,因为它现在可以处理此类问题(请参阅this)。

所以我尝试了,

def save_related(self, request, form, formsets, change):
    #Added logic here using form.instance
    return super(SomeModelAdmin, self).save_related(request, form, formsets, change)

但我的行为与上述相同,在使用我的逻辑时似乎没有保存更改。我在这里做错了吗?

编辑

这里有更多信息。基本上,我在change_form.html 中添加了一个自定义按钮,这会触发一个自定义方法。所以,

def save_related(self, request, form, formsets, change):
    if 'MyButton' in request.POST:
    #Added logic here using form.instance
    return super(SomeModelAdmin, self).save_related(request, form, formsets, change)

因此,通过这样做,除了已经包含的内置保存方法之外,我还向 django admin 添加了一个新的自定义行为。换句话说,该按钮可用于同时操作数据和保存模型。

现在,我的问题是,当MyButton 被触发并调用自定义逻辑时,如果有人在其中一个内联中进行了更改,则添加的逻辑不会考虑它,因为它尚未保存在数据库中。

【问题讨论】:

  • 您能添加更多代码和示例吗?目前尚不清楚预期结果和实际(不想要的)结果是什么。
  • 好吧,我可以提供的代码不多了。预期结果是在保存表单中存在的所有模型后,在情况 1 中操作 obj 和在情况 2 中操作 form.instance(它们相同)。所以,我想覆盖正确的保存方法。根据我的发现,save_related 在保存所有模型(包括内联实例)后被调用。
  • @HåkenLid 更新问题。
  • @HåkenLid 你还不清楚吗?
  • save_related中的自定义逻辑是什么?如果您包含一个完整的示例,将更容易理解。 minimal reproducible example 为什么不先做super().save_related(),然后是自定义逻辑?这个方法总是返回None,所以你不需要显式的返回语句。 docs.djangoproject.com/en/1.11/_modules/django/contrib/admin/…

标签: python django python-3.x django-admin


【解决方案1】:

如果自定义逻辑必须在相关对象保存后发生,只需调用super()方法即可。

class SomeModelAdmin(ModelAdmin):

    def save_related(self, request, *args, **kwargs):
        super().save_related(request, *args, **kwargs)

        if 'MyButton' in request.POST:
            #Added logic here using form.instance

由于您使用的是 python 3,因此您不需要将任何参数传递给 super()。此外,由于ModelAdmin.save_related 始终返回None,因此您也不需要在save_related 中使用return 语句。

【讨论】:

  • 我会接受,因为它有效,但如果你能解释一下,那就太棒了:由于你使用的是 python 3,你不需要向 super() 传递任何参数 i> 为什么你说 ModelAdmin.save_related 总是返回 None,你的 save_related 中也不需要 return 语句。
  • 在python3中,你可以调用内置的super()不带参数。如果您编写的代码也必须与 python2 一起使用,则需要使用super(SomeModelAdmin, self) 调用它。由于即将发布的 django 版本根本不支持 python 2.7,你还不如只为 python 3.x 编写代码。
  • 如果您阅读ModelAdmin.save_related 的源代码,您会发现它没有return' statement. It will always return None'。因此,当您在子类中覆盖该方法时,您也可以返回Nonedocs.djangoproject.com/en/1.11/_modules/django/contrib/admin/…