title: Django Admin Custom Change List Arguments: Override /?e=1
body: <p>I'm trying to pass in a custom argument to the Django Admin change list view so I can filter the list in a specialized way.  I'd like to filter the queryset on 2 fields, start_date and end_date, based on the GET parameter called 'active_pp'.  I've gotten the filtering to work correctly, but I'm not able to pass in a GET query parameter that specifies whether I should display the filtered results or the normal results. </p>
  
  <p>I know that, due to security, the Django Admin filters out any query parameters passed to it that aren't related to specified model fields; upon finding bad arguments, the admin redirects the user to the current view but replaces the GET query parameters with e=1.  I'd like to whitelist my custom 'active_pp' parameter so the page won't be redirected and I'll be able to use the parameter.</p>
  
  <p>Here is an example of the ModelAdmin in admin.py with the queryset customization. </p>
  
  <pre><code>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))
                               &amp; (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
  </code></pre>
  
  <p>Does anyone know how to whitelist custom GET querystring arguments passed to the change_list?  </p>
  
  <p>Thanks for reading and for your consideration,
  Joe</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Using Uvasal's provided links, I was able to properly whitelist the GET parameter.  </p>
  
  <pre><code>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))
                                   &amp; (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)
  </code></pre>