2010-08-21 2 views
10

Desidero personalizzare il modo in cui le query di ricerca tra i campi di ricerca.Django admin search: come sovrascrivere il gestore predefinito?

C'è un modo per farlo senza incidere profondamente nel codice Django o creare una visione totalmente indipendente?

Ad esempio, desidero restituire l'unione dei set di query per ciascuno degli elementi di querystring.split(). In questo modo, la ricerca di "apple bar" restituirebbe risultati con EITHER o OR bar, a differenza della ricerca predefinita che applica un operatore AND.

+1

Si prega di elaborare quale comportamento esattamente si desidera raggiungere. Idealmente fornire un esempio. –

+0

Ho appena aggiunto un esempio –

+0

Ho aggiornato la mia risposta, puoi leggerla e modificarla, quindi provare – WeizhongTu

risposta

0

è possibile aggiungere un metodo ModelAdmin:

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 

avete una richiesta qui, quindi la maggior parte delle cose può essere vista dipendente, compresi i parametri URL, i cookie, sessioni ecc

9

E 'molto facile farlo in django 1.6

ModelAdmin.get_search_results(request, queryset, search_term) Novità 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

Così ho usato il codice dalla risposta di WeizhongTu e ho trovato un errore non così ovvio in esso. Quando cerchiamo di utilizzare sia il filtraggio e la ricerca con questo codice, il filtraggio viene pedinato da questa linea:

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

E 'importante utilizzare i risultati precedenti SOLO. Pertanto non è necessario utilizzare mai self.model.objects per ottenere il set di query, ma filtrare solo il set di query stesso. In questo modo:

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