2011-12-13 78 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