2011-12-13 76 views
14

我試圖將一個自定義參數傳遞給Django Admin更改列表視圖,以便我可以以專門的方式過濾列表。我想根據名爲'active_pp'的GET參數篩選2個字段的查詢集start_date和end_date。我已經使篩選正常工作,但我無法傳入GET查詢參數,該參數指定是否應顯示篩選結果或正常結果。Django管理自定義更改列表參數:覆蓋/?e = 1

我知道,由於安全性,Django Admin會過濾掉傳遞給它的任何查詢參數,這些查詢參數與指定的模型字段無關;一旦發現錯誤的參數,管理員將用戶重定向到當前視圖,但用e = 1替換GET查詢參數。我想將我的自定義'active_pp'參數列入白名單,以便頁面不會被重定向,我可以使用該參數。

以下是admin.py中的ModelAdmin與查詢集定製的示例。

class FeaduredAdmin(admin.ModelAdmin): 

    .... 

    def get_changelist(self, request, **kwargs): 
     from django.contrib.admin.views.main import ChangeList 

     # Try to get the 'active_pp' query parameter 
     active_pp = request.GET.get('active_pp',None) 

     # Define a custom ChangeList class with a custom queryset 
     class ActiveChangeList(ChangeList): 
      def get_query_set(self, *args, **kwargs): 
       now = datetime.datetime.now() 
       qs = super(ActiveChangeList, self).get_query_set(*args, **kwargs) 
       return qs.filter((Q(start_date=None) | Q(start_date__lte=now)) 
          & (Q(end_date=None) | Q(end_date__gte=now))) 

     # use the custom ChangeList class if the parameter exists 
     if active_pp: 
      return ActiveChangeList 

     return ChangeList 

有誰知道如何將傳遞給change_list的自定義GET查詢字符串參數白名單?

感謝您的閱讀,併爲您考慮, 喬

UPDATE:

使用Uvasal的提供的鏈接,我能夠正確白名單的GET參數。

class ActiveFilterAminForm(forms.Form): 
    active_pp = forms.CharField() 

class FeaduredAdmin(admin.ModelAdmin): 

    .... 

    # Based on: http://djangosnippets.org/snippets/2322/ 
    advanced_search_form = ActiveFilterAminForm() 

    def get_changelist(self, request, **kwargs): 

     from django.contrib.admin.views.main import ChangeList 
     active_pp = self.other_search_fields.get('active_pp',None) 
     # now we have the active_pp parameter that was passed in and can use it. 

     class ActiveChangeList(ChangeList): 

      def get_query_set(self, *args, **kwargs): 
       now = datetime.datetime.now() 
       qs = super(ActiveChangeList, self).get_query_set(*args, **kwargs) 
       return qs.filter((Q(start_date=None) | Q(start_date__lte=now)) 
           & (Q(end_date=None) | Q(end_date__gte=now))) 

     if not active_pp is None: 
      return ActiveChangeList 

     return ChangeList 


    def lookup_allowed(self, lookup): 
     if lookup in self.advanced_search_form.fields.keys(): 
      return True 
     return super(MyModelAdmin, self).lookup_allowed(lookup) 


    def changelist_view(self, request, extra_context=None, **kwargs): 
     self.other_search_fields = {} 
     asf = self.advanced_search_form 
     extra_context = {'asf':asf} 

     request.GET._mutable=True 

     for key in asf.fields.keys(): 
      try: 
       temp = request.GET.pop(key) 
      except KeyError: 
       pass 
      else: 
       if temp!=['']: 
        self.other_search_fields[key] = temp 

     request.GET_mutable=False 
     return super(FeaduredProductAdmin, self)\ 
       .changelist_view(request, extra_context=extra_context) 
+0

這似乎是一個有用的功能,有適當的DRY django支持。 – dashesy 2015-03-25 17:53:11

回答

6

我認爲你需要把你的自定義過濾器領域的search_fields類變量作爲Advanced Search Django的片段概述。

您應該可以修改片段以支持日期範圍。

+0

感謝Uvasal。你提供的鏈接確實有幫助。我已經使用基於您提供的實現更新了我的代碼。 - Joe – 2011-12-13 21:15:25

3

總之,這裏是上面所用的無證黑客:

設置request.GET._mutable = True,然後request.GET.pop()關閉正在使用的自定義GET參數(S)。

+0

注意到`request.GET.pop(key)`得到一個列表 – WeizhongTu 2017-01-10 12:28:54