22

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

セキュリティ上の理由から、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 クエリ文字列引数をホワイトリストに登録する方法を知っている人はいますか?

読んでくれてありがとう、ジョー

アップデート:

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)
4

3 に答える 3

7

Advanced Search Django Snippetで説明されているように、カスタム フィルター フィールドを search_fields クラス変数に入れるだけでよいと思います。

日付範囲もサポートするようにスニペットを変更できるはずです。

于 2011-12-13T19:28:02.333 に答える
5

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

set request.GET._mutable = True、次にrequest.GET.pop()使用しているカスタム GET 引数をオフにします。

于 2014-04-21T20:36:00.497 に答える