我希望自定义search_fields中搜索查询的方式。
有没有办法在不深入研究Django代码或创建完全独立的视图的情况下实现呢?
例如,我想为querystring.split()的每个项返回查询集的并集。因此,搜索“apple bar”将返回带有EITHER apple OR bar的结果,这与应用AND运算符的默认搜索不同。
答案 0 :(得分:11)
在django 1.6中很容易做到这一点
ModelAdmin.get_search_results(request, queryset, search_term) Django 1.6中的新内容。
import operator
# from django.utils.six.moves import reduce # if Python 3
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 = reduce(operator.or_, [Q(**{c:v}) for c in search_columns for v in search_term_list])
queryset = self.model.objects.filter(query_condition)
# NOTICE, if you want to use the query before
# queryset = queryset.filter(query_condition)
return queryset, use_distinct
答案 1 :(得分:0)
您可以添加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
你在这里有一个请求,所以大多数东西都可以依赖于视图,包括url参数,cookie,会话等。
答案 2 :(得分:0)
所以我一直在使用WeizhongTu的答案,并发现了一个不那么明显的错误。当我们尝试使用此代码进行过滤和搜索时,过滤将被此行遮蔽:
queryset = self.model.objects.filter(eval(query_condition))
仅使用之前的结果非常重要。因此,您绝不能使用self.model.objects
来获取查询集,而只是过滤查询集本身。像这样:
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