2011-12-13 2 views
14

Я пытаюсь передать пользовательский аргумент в список изменений в списке Django Admin, чтобы я мог отфильтровать список специальным способом. Я хотел бы отфильтровать запрос на 2 поля, start_date и end_date, на основе параметра GET, называемого «active_pp». Я получил фильтрацию, чтобы работать правильно, но я не могу передать параметр запроса GET, который указывает, следует ли отображать отфильтрованные результаты или обычные результаты.Django Admin Custom Change List Аргументы: Override /? E = 1

Я знаю, что из-за безопасности Django Admin фильтрует любые переданные ему параметры запроса, которые не связаны с указанными полями модели; при поиске плохих аргументов администратор перенаправляет пользователя в текущее представление, но заменяет параметры запроса GET на e = 1. Я бы хотел, чтобы белый список моего настраиваемого параметра «active_pp», чтобы страница не перенаправлялась, и я смогу использовать этот параметр.

Ниже приведен пример ModelAdmin в admin.py с настройкой запроса.

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 

Кто-нибудь знает, как настроить белый список настраиваемых аргументов запроса GET, переданных в change_list?

Спасибо за чтение и для вашего рассмотрения, Джо

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

Я думаю, вам просто нужно положить ваши пользовательские поля фильтра в переменной search_fields класса, как указано в Advanced Search Джанго Snippet.

Вы также сможете изменить фрагмент, чтобы поддерживать диапазоны дат.

+0

Спасибо Uvasal. Ссылка, которую вы предоставили, действительно помогла. Я обновил свой код выше с реализацией на основе того, что вы предоставили. - Joe –

3

В общем, здесь без документов хак используется выше:

набор request.GET._mutable = True, затем request.GET.pop() от пользовательской GET аргумента (ы) вы используете.

+0

Обратите внимание, что 'request.GET.pop (key)' получить список – WeizhongTu