Python Django - 可读语法的过滤和包含

0 投票
2 回答
1272 浏览
提问于 2025-04-16 17:41

我写了一个简单的搜索方法,但发现它有点难读,排序也有点乱。请问有什么好的方法可以让查询过滤得更好呢?

@login_check
def search(request):
    subdomain = request.get_host()                                                                   
    q = request.GET.get('q', None)
    queryset = (
                    SomeObject.objects.filter(title__icontains=q)
                        .filter(alias=Site.objects.get(domain=subdomain)) \
                        .order_by('created') |
                    SomeObject.objects.filter(description__icontains=q)
                        .filter(alias=Site.objects.get(domain=subdomain)) \
                        .order_by('created') |
                    SomeObject.objects.filter(comment__icontains=q)
                        .filter(alias=Site.objects.get(domain=subdomain)) \
                        .order_by('created') |
                    SomeObject.objects.filter(email__icontains=q)
                        .filter(alias=Site.objects.get(domain=subdomain)) \
                        .order_by('created')
                )
    return object_list(queryset)

在这个方法中,返回的对象列表就是我需要的,所以我只需要构建一个好的查询。

我觉得主要的问题是,过滤器可以在contains之后应用,因为它们都是一样的。我该怎么做才能实现这个呢?在这种情况下,过滤的最佳或最好的方法是什么?

我尝试在创建查询后设置过滤器,但系统提示我不能将过滤器应用于查询,只能应用于模型列表。我可能记错了,因为我是在回忆这个错误,但可以肯定的是,确实出现了错误。

附注:我在这里使用的是Django 1.1和Python 2.5。

2 个回答

1

你可以使用列表推导式来提取出共同的部分:

queryset_list = (
    item.filter(alias=Site.objects.get(domain=subdomain)).order_by('created')
    for item in (
        SomeObject.objects.filter(title__icontains=q),
        SomeObject.objects.filter(description__icontains=q),
        SomeObject.objects.filter(comment__icontains=q),
        SomeObject.objects.filter(email__icontains=q)))
queryset = functools.reduce(operator.or_, queryset_list)

撰写回答