1

例如,如何区分来自常规视图的 post_save 和来自管理员的 post_save?

4

2 回答 2

3

通过覆盖 ModelAdmin.response_add 您可能会获得类似的功能,因为 django 管理员似乎没有发送任何信号。

response_add 函数在成功验证并添加所有数据(例如相关字段以及对象本身)后被调用。

因此,通过覆盖我们自己的 ModelAdmin 类中的 response_add 方法,我们可以在管理中的某些内容成功添加后执行代码,但不会在其他地方执行。

我在 django 1.4 中做了以下方式,非常感谢任何评论或反馈!就我而言,它似乎运行良好,但我对 Django 中的所有内部结构还不是很熟悉,如果这是一种建议的方法。但对我来说,这听起来比 threadlocal hack 要好。

旁注:我想您也可以通过覆盖 ModelAdmin 自己触发信号,但没有经验。

这是我用来覆盖 response_add 的代码,它将执行 product_get_initial_info(obj.id) 只有在管理员中成功添加了一个产品:

class ProductAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}
    inlines = [
        ProductInline,
    ]
    def response_add(self, request, obj, post_url_continue='../%s/'):
        if obj and obj.id:
            tasks.product_get_initial_info(obj.id)
        return super(ProductAdmin, self).response_add(request, obj, post_url_continue='../%s/')

相关的django源码在这里: django/contrib/admin/options.py

class ModelAdmin(BaseModelAdmin):
    def add_view(self, request,...)
        # .... Many lines of code ...... not putting them here as they're not so relevant
        if all_valid(formsets) and form_validated:
            self.save_model(request, new_object, form, False)
            self.save_related(request, form, formsets, False)
            self.log_addition(request, new_object)
            # After saving everything response_add gets called with the newly created object
            return self.response_add(request, new_object)
于 2012-10-06T09:55:32.223 回答
2

没有一种简单的方法可以做到这一点,这对我来说意味着您可能没有使用 post_save 信号将代码放在正确的位置。

也就是说,如果您真的想要,您可以使用 threadlocal hack 来访问请求对象并确定当前运行的视图是否是管理视图。要了解如何执行 threadlocal hack,请从django 食谱开始,但只需保存整个请求而不是用户。请注意,很多人认为 threadlocal hack 是可憎的。这是一个讨论。我认为他们有一个非常有用的地方,但是在不了解更多信息的情况下,我猜想您有更好的解决方案。

于 2011-03-14T23:11:48.430 回答