基于可选参数的Django过滤

12

我有一份可选参数列表,用于在Django中进行筛选,现在正试图找出最佳方案来应用这些过滤器。我的第一个想法是像下面这样做:

if param_1 != 'all' and param_2 != 'all': # etc.
    class_var = ClassName.objects.filter(param_1__name=param_1, param_2__name=param_2) # etc.
else:
    class_var = ClassName.objects.all()

但由于所有参数都是可选的,我可能只想基于param_1进行过滤,并将其余参数设置为'all'。当然,另一个选项是说:

class_var = ClassNam.objects.all()
if param_1 != 'all':
    class_var.filter(param_1__name=param_1)

if param_2 != 'all':
    class_var.filter(param_2__name=param_2)

# etc.

但在我看来,这似乎不是非常高效的。我只是希望能够得到一些其他执行这些选项筛选的方法的想法。

4个回答

23

你实际上可以做什么

from django.db.models import Q

q = Q()
if param_1 != 'all':
    q &= Q(param_1__name=param_1)

if param_2 != 'all':
    q &= Q(param_2__name=param_2)

class_var = ClassName.objects.filter(q)

OR

q = {}
if param_1 != 'all':
    q.update({'param_1__name': param_1})

if param_2 != 'all':
    q.update({'param_2__name': param_2})

class_var = ClassName.objects.filter(**q)

1
欢迎来到StackOverflow,并感谢您的尝试帮助。与解释解决方案的答案相比,像您这样的仅包含代码的答案受到的赞赏较少。请阅读此如何回答问题 - thewaywewere

9

您可能需要了解Q对象。简单来说,Q允许您在查询中使用OR语句。从上述链接的页面中可以了解到:

Polls.objects.filter(
    Q(question__startswith='Who') | Q(question__startswith='What')
)

这将提取以“谁”或“什么”开头的问题。

3
使用Q对象并制作一个查询列表。
q=[]
if param_1 != 'all':
   q.append(Q(param_1__name=param_1))
if param_2 != 'all':
   q.append(Q(param_2__name=param_2))

details = ClassName.objects.filter(reduce(AND, q))

1

查询集是惰性的。只有在查询集被评估(通常通过迭代)时才会进行数据库查询。您可以自由地应用尽可能多的过滤器,几乎没有任何成本。

注意: filter() 不会更改查询集,而是返回一个新的查询集。应用其他过滤器的正确方法是:

class_var = class_var.filter(param_1__name=param_1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接