2010-08-21 23 views
10

Deseo personalizar la forma en que se realizan las consultas de búsqueda en los campos de búsqueda.búsqueda de administrador de Django: cómo anular el controlador predeterminado?

¿Hay alguna manera de hacerlo sin hackear profundamente el código de Django o crear una vista totalmente independiente?

Por ejemplo, me gustaría devolver la unión de los conjuntos de consulta para cada uno de los elementos de la querystring.split(). De modo que la búsqueda de "barra de manzanas" devolvería los resultados con CUALQUIER manzana O barra, a diferencia de la búsqueda predeterminada que aplica un operador AND.

+1

Por favor, elabore qué comportamiento exactamente le gustaría lograr. Idealmente da un ejemplo. –

+0

Acabo de agregar un ejemplo –

+0

Actualicé mi respuesta, puede leerla y editarla, luego pruebe – WeizhongTu

Respuesta

0

se puede añadir una ModelAdmin método:

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 

tiene una solicitud aquí, así que la mayoría de las cosas puede ser vista dependiente, incluyendo parámetros, cookies, sesiones, etc.

9

Es muy fácil de hacer esto en django 1.6

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

Así que han estado utilizando el código de la respuesta de WeizhongTu y encontró un error no tan obvia en ella. Cuando tratamos de utilizar tanto el filtrado y la búsqueda con este código, el filtrado se ve ensombrecido por esta línea:

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

Es importante utilizar los resultados anteriores SOLAMENTE. Por lo tanto, nunca debe usar self.model.objects para obtener el conjunto de consultas, sino solo filtrar el conjunto de consultas. De esta manera:

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 
Cuestiones relacionadas