2011-12-13 15 views
14

Sto provando a passare un argomento personalizzato alla vista elenco modifiche Django Admin in modo da poter filtrare l'elenco in un modo specializzato. Vorrei filtrare il queryset su 2 campi, start_date e end_date, in base al parametro GET chiamato 'active_pp'. Ho ottenuto il filtraggio per funzionare correttamente, ma non sono in grado di passare un parametro di query GET che specifica se dovrei visualizzare i risultati filtrati oi risultati normali.Argomenti Django Admin Custom Change List: Override /? E = 1

So che, a causa della sicurezza, Django Admin filtra tutti i parametri di ricerca passati che non sono correlati ai campi del modello specificati; dopo aver trovato argomenti non validi, l'amministratore reindirizza l'utente alla vista corrente ma sostituisce i parametri di query GET con e = 1. Vorrei autorizzare il mio parametro personalizzato "active_pp" in modo che la pagina non venga reindirizzata e potrò utilizzare il parametro.

Ecco un esempio di ModelAdmin in admin.py con la personalizzazione del queryset.

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 

Qualcuno sa come whitelist personalizzate ottenere gli argomenti passati al QueryString change_list?

Grazie per la lettura e per la vostra considerazione, Joe

UPDATE:

Usando link forniti di Uvasal, sono stato in grado di whitelist correttamente il parametro 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

Questa sembra essere una funzionalità abbastanza utile per avere il supporto DRY django adeguato. – dashesy

risposta

6

Penso solo bisogno di mettere i campi filtro personalizzato nella variabile search_fields classe come indicato nella Advanced Search Django Snippet.

Dovresti essere in grado di modificare lo snippet per supportare anche intervalli di date.

+0

Grazie Uvasal. Il link che hai fornito mi è stato di grande aiuto. Ho aggiornato il mio codice sopra con l'implementazione in base a ciò che hai fornito. - Joe –

3

In sintesi, ecco il trucco non documentato utilizzato in precedenza:

impostato request.GET._mutable = True, poi request.GET.pop() fuori l'argomento GET personalizzato (s) che si sta utilizzando.

+0

avviso che 'request.GET.pop (chiave)' ottiene una lista – WeizhongTu