Django signals from admin

此生再无相见时 提交于 2021-02-16 09:24:10

问题


How can I distinguish between, for example, a post_save that comes from a regular view and one that comes from the admin?


回答1:


By overriding ModelAdmin.response_add you may get a similar functionality, as it seems that the django admin does not sent any signals.

The response_add function gets called after it successfully validated and added all data, such as related fields but also the object itself.

So by overriding the response_add method in our own ModelAdmin class we can execute code after something in the admin got added successfully, but won't be executed somewhere else.

I did the following way in django 1.4, any comments or feedback greatly appreciated! It seems to be working well in my case, but I'm not so familiar with all the internals in Django yet and if it's a suggested way to do it. But it sounds better than a threadlocal hack to me.

Side note: I guess you could also fire signals yourself by overriding the ModelAdmin, but not experience with that.

This is the code I used to override response_add, which will execute product_get_initial_info(obj.id) only a product was successfully added in the admin:

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/')

The related django source code is here: 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)



回答2:


There's not a straightforward way to do this, which implies to me you might not putting your code in the right place by using the post_save signal.

That said, if you really want to, you could use a threadlocal hack to get access to the request object and figure out if the currently running view is an admin view. To read about how to do the threadlocal hack, start in the django cookbook but just save the whole request instead of the user. Note that lots of people think threadlocal hacks are an abomination. Here's a discussion. I think they have a very useful place, but without knowing more, I'd guess there's a better solution for you.



来源:https://stackoverflow.com/questions/5305520/django-signals-from-admin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!