2011-12-13 11 views
14

Django Adminの変更リストビューにカスタム引数を渡そうとしているので、特別な方法でリストをフィルタリングできます。私は2つのフィールド、start_dateとend_date、 'active_pp'と呼ばれるGETパラメータに基づいてクエリセットをフィルタリングしたいと思います。フィルタリングが正しく機能するようにしましたが、フィルタリングされた結果を表示するか、通常の結果を表示するかを指定するGETクエリパラメータを渡すことができません。Django Adminのカスタム変更リスト引数:Override /?e = 1

セキュリティのために、Django Adminは、指定されたモデルフィールドに関連していないクエリパラメータをフィルタリングして除外します。不正な引数が見つかると、管理者はユーザーを現在のビューにリダイレクトしますが、GETクエリパラメータをe = 1に置き換えます。私は私のカスタム '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

答えて

6

私はあなただけAdvanced Searchジャンゴスニペットに概説されているようsearch_fieldsクラス変数にカスタムフィルタフィールドを配置する必要があると思います。

日付範囲もサポートするようにスニペットを修正する必要があります。

+0

Uvasalありがとうございます。あなたが提供したリンクが本当に助けになりました。上記のコードを、あなたが提供したものに基づいて実装で更新しました。 - Joe –

3

要約すると、ここでは上記の使用文書化されていないハックは以下のとおりです。

は、使用しているカスタムGET引数(複数可)オフ、その後request.GET._mutable = Truerequest.GET.pop()を設定します。

+0

'request.GET.pop(key)'がリストを取得することに注意してください – WeizhongTu

関連する問題