2011-03-14 52 views

回答

2

有沒有一種簡單的方法來做到這一點,這意味着你可能不會使用post_save信號將你的代碼放在正確的位置。這就是說,如果你真的想,你可以使用threadlocal hack來訪問請求對象,並確定當前正在運行的視圖是否是管理視圖。要了解如何執行threadlocal攻擊,請從django cookbook開始,但只保存整個請求而不是用戶。請注意,很多人認爲threadlocal攻擊是可憎的。這是一個discussion。我認爲他們有一個非常有用的地方,但不知道更多,我猜想有一個更好的解決方案給你。

2

通過覆蓋ModelAdmin.response_add,您可能會得到類似的功能,因爲django admin似乎沒有發送任何信號。

response_add函數在成功驗證並添加了所有數據(例如相關字段,但也包括對象本身)之後被調用。

因此,通過覆蓋我們自己的ModelAdmin類中的response_add方法,我們可以在管理員添加成功後執行代碼,但不會在其他地方執行。

我在django 1.4中做了以下的方法,任何意見或反饋非常感謝!對我而言,它似乎運行良好,但我對Django中的所有內部結構並不熟悉,並且它是建議的方式。但這聽起來比對我的一個線索本地攻擊更好。

附註:我想你也可以通過覆蓋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)