【问题标题】:Dynamic filter in DjangoDjango中的动态过滤器
【发布时间】:2021-05-15 21:55:51
【问题描述】:

在我的应用程序中,我有一个表单。根据表单的不同,用户可以配置一个或多个过滤器。

在我看来,我有例子:

query = Test.objects.filter(filter1 = request.post['filter1'], filter2 = request.post['filter2'], filter3 = request.post['filter3'])

所以,有时 filter1、filter2 或 filter3 不存在。

如果任何过滤器不存在,我只想忽略过滤器。

我可以编写一个包含许多“IF”条件的脚本,但可能有一个聪明的解决方案吗?

感谢您的帮助!

【问题讨论】:

  • 用参数创建一个字典并像.filter(**your_dict)一样调用filter

标签: python django


【解决方案1】:

你可以按照以下方式做一些事情:

filters = {}

for key, value in request.post.items():
    if key in ['filter1', 'filter2', 'filter3']:
        filters[key] = value

Test.objects.filter(**filters)

其中列表是您打算过滤的键列表


编辑

正如Thomas Junk 建议的那样,您可以通过理解使其更清晰:

filters = {
    key: value
    for key, value in request.post.items()
    if key in ['filter1', 'filter2', 'filter3']
}

Test.objects.filter(**filters)

【讨论】:

  • 根据口味,可以写出理解。但这似乎可以解决问题。
  • 太棒了!谢谢!
  • 快速问题:如何在这种方法中使用大于或小于之类的东西?
  • @krishnalodha 您可以将密钥/参数设置为 filter1__gte=10
【解决方案2】:

这段代码解决了我的问题:

if request.method == 'GET':
        filters = {}
        for key, value in request.GET.items():
            if value != '':
                filters[key] = value
        filter_list=Pet.objects.filter(**filters)

【讨论】:

    【解决方案3】:

    你可以这样使用:

    import ast
    
    
    def query_to_dict(query) -> dict:
        filters = {}
        for field, value in query.items(): #  <- param and value like ?param1=True
            filters[field] = ast.literal_eval(str(value)) #  <- parse list/str/bool
    
        return filters
    
    def event_view(request):
        events = Event.objects.filter(
            Q(**query_to_dict(request.GET))
        )
    
        return Response(
            EventsSerializer(events, many=True).data
        )
    

    在这个例子中:

    ast - 有助于解析布尔值和列表的模块

    request.GET - 这是您的查询参数?param1=True&amp;param2="[1, 2]"。确保以?title="hello" 之类的方式传递参数 - 使用双引号

    query_to_dict - 将查询参数转换为 python dict 的函数。所以你可以把这个字典传给你的Event.objects.filter

    以这种方式使用过滤的好处,你可以传递?id__in="[1, 2]" 这样的东西,它会起作用。我不能确定它是否安全,但对于一些复杂的过滤或布尔字段过滤来说,它是完美的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      • 2011-08-11
      • 1970-01-01
      • 2016-01-20
      • 1970-01-01
      • 2015-03-12
      相关资源
      最近更新 更多