2010-08-21 8 views
10

Ich möchte die Art und Weise anpassen, in der Suchanfragen über die search_fields.Django admin search: Wie überschreibt man den Standard-Handler?

Gibt es eine Möglichkeit, dies zu tun, ohne tief in den Django-Code zu hacken oder eine völlig unabhängige Ansicht zu erstellen?

Zum Beispiel möchte ich die Union der Abfragegruppen für jedes der Elemente der querystring.split() zurückgeben. So dass die Suche nach "Apfel-Bar" Ergebnisse mit ENTWEDER Apfel oder Bar zurückgibt, im Gegensatz zu der Standard-Suche, die einen AND-Operator anwendet.

+1

Bitte erläutern Sie, welches Verhalten genau Sie erreichen möchten. Idealerweise ein Beispiel geben. –

+0

Ich habe gerade ein Beispiel hinzugefügt –

+0

Ich aktualisierte meine Antwort, Sie können es lesen und bearbeiten, dann versuchen Sie es – WeizhongTu

Antwort

0

können Sie eine ModelAdmin Methode hinzufügen:

def queryset(self, request): 
    qs = super(MyModelAdmin, self).queryset(request) 
    # modify queryset here, eg. only user-assigned tasks 
    qs.filter(assigned__exact=request.user) 
    return qs 

Sie haben eine Anfrage hier, so die meisten Sachen kann Ansicht abhängig sein, einschließlich der URL-Parameter, Cookies, Sitzungen usw.

9

Es ist sehr leicht zu tun dies in django 1.6

ModelAdmin.get_search_results(request, queryset, search_term) Neu in Django 1.6.

from django.db.models import Q 

class PersonAdmin(admin.ModelAdmin): 
    list_display = ('name', 'age') 
    search_fields = ('name',) 

    def get_search_results(self, request, queryset, search_term): 
     # search_term is what you input in admin site 
     # queryset is search results 
     queryset, use_distinct = super(PersonAdmin, self).get_search_results(request, queryset, search_term) 

     search_term_list = search_term.split(' ')#['apple','bar'] 
     # you can also use `self.search_fields` instead of following `search_columns` 
     search_columns = ('name','age','address') 
     #convert to Q(name='apple') | Q(name='bar') | Q(age='apple') | ... 
     query_condition = ' | '.join(['Q(%s="%s")'%(x,y) for x in search_term_list for y in search_columns]) 
     queryset = self.model.objects.filter(eval(query_condition)) 

     return queryset, use_distinct 
0

So verwendet Ich habe in ihm den Code aus WeizhongTu Antwort und fand einen nicht so offensichtlichen Fehler. Wenn wir versuchen, beide Filterung zu verwenden und mit diesem Code suchen, ist das Filtern von dieser Linie beschattet:

queryset = self.model.objects.filter(eval(query_condition))

Es ist wichtig, nur die bisherigen Ergebnisse zu verwenden. Sie dürfen also nie self.model.objects verwenden, um das Abfrage-Set zu erhalten, sondern nur das Abfrage-Set selbst filtern. Wie folgt:

def get_search_results(self, request, queryset, search_term): 
    # search_term is what you input in admin site 
    # queryset is the list of objects passed to you 
    # by the previous functions, e. g. filtering 
    search_term_list = search_term.split(' ') #['apple','bar'] 
    search_columns = ('name','age','address') 
    # convert to Q(name='apple') | Q(name='bar') | Q(age='apple') | ... 
    query_condition = ' | '.join(['Q(%s="%s")'%(x,y) for x in search_term_list for y in search_columns]) 
    appended_queryset = queryset.filter(eval(query_condition)) 
    # queryset is search results 
    queryset, use_distinct = super(PersonAdmin, self).get_search_results(request, queryset, search_term) 
    queryset |= appended_queryset 
    return queryset, use_distinct 
Verwandte Themen