Django 基于可选参数的过滤

Django filtering based on optional parameters

我有一个可选参数列表,我正在使用这些参数在 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.

但在我看来,这似乎并不是很有效。我只是希望获得一些关于我可能能够执行这些选项过滤器的其他方式的想法。

您可能需要查看 Q objects。简而言之,Q 允许您在查询中使用 OR 语句。来自前面链接的页面:

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

这将提取以“Who”或“What”开头的问题。

查询集是惰性的。在查询集被评估之前不会有数据库查询,通常是通过迭代。您几乎可以免费应用任意数量的过滤器。

请注意:filter() 不会更改查询集,而是 returns 一个新的查询集。应用附加过滤器的正确方法是:

class_var = class_var.filter(param_1__name=param_1)

使用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))

您实际上可以做什么

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)