Django 管理搜索:如何覆盖默认处理程序?

发布于 2024-09-16 02:25:45 字数 198 浏览 4 评论 0原文

我希望自定义跨 search_fields 进行搜索查询的方式。

有没有一种方法可以做到这一点,而无需深入 Django 代码或创建完全独立的视图?

例如,我想返回 querystring.split() 的每个项目的查询集的并集。因此,搜索“apple bar”将返回带有 apple OR bar 的结果,这与应用 AND 运算符的默认搜索不同。

I wish to customize the way in which search queries across the search_fields.

Is there a way to do it without hacking deeply into the Django code or creating a totally independent view?

For instance, I would like to return the union of the querysets for each of the items of the querystring.split(). So that searching for "apple bar" would return results with EITHER apple OR bar, unlike the default search which applies an AND operator.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

没有心的人 2024-09-23 02:25:45

在 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

It is very easy to do this in django 1.6

ModelAdmin.get_search_results(request, queryset, search_term) New in 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
鸩远一方 2024-09-23 02:25:45

所以我一直在使用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

So I have been using the code from WeizhongTu's answer and found a not-so-obvious error in it. When we try to use both filtering and searching with this code, filtering is shadowed by this line:

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

It is important to use the previous results ONLY. So you must never use self.model.objects to obtain the queryset, but only filter the queryset itself. Like this:

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
作业与我同在 2024-09-23 02:25:45

您可以添加一个 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、会话等。

you can add an ModelAdmin method:

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

you have a request here, so most of the stuff can be view dependent, including url parameters, cookies, sessions etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文