【问题标题】:Django filtering based on optional parameters基于可选参数的Django过滤
【发布时间】:2015-08-12 20:37:50
【问题描述】:

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

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

【问题讨论】:

    标签: python django django-queryset


    【解决方案1】:

    你实际上可以做什么

    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)
    

    【讨论】:

    • 欢迎来到 StackOverflow 并感谢您提供帮助。与解释解决方案的答案相比,像您这样的纯代码答案不太受欢迎。请阅读此how-to-answer
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      class_var = class_var.filter(param_1__name=param_1)
      

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2019-04-27
          • 2019-10-08
          • 2021-04-10
          • 1970-01-01
          • 1970-01-01
          • 2020-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多