如何实现多个过滤器 Django?

Posted

技术标签:

【中文标题】如何实现多个过滤器 Django?【英文标题】:How to implement multiple filters Django? 【发布时间】:2021-08-31 00:44:50 【问题描述】:

我想将这样的过滤器添加到我的网上商店:

Color:
 # red
 # blue
 # green
Material:
 # plastic
 # wood
 # metal

其中每个点都是一个复选框,颜色和材质是一些 Django 模型的字段。

例如,如果我正在寻找带有塑料材料的红色或蓝色玩具,我会这样找到它:

filtered = SomeModel.objects.filter(material=plastic, color=red, color=blue)

但是如何动态过滤呢?(如果我有很多过滤器)

【问题讨论】:

看看这个包:django-filter.readthedocs.io/en/stable 【参考方案1】:

你可以这样做

query = SomeModel.objects.filter(material='plastic')
if any_bool_condition:
    query = query.filter(color='red')

您可以继续在query 上添加filter

对于 OR 条件,您应该查看 https://***.com/a/6567918/3864717

【讨论】:

如果 idk 用户检查了什么颜色和过滤器怎么办?【参考方案2】:
# Import
from django.db.models import Q

filter_query = Q()

# Get colors to be filtered
filter_color_list = ['red', 'blue']

# Add Filter by colors
filter_query.add(Q(color__in=filter_color_list), Q.AND)

# Get materials to be filtered
filter_material_list = ['plastic']

# Add filter by material
filter_query.add(Q(material__in=filter_material_list), Q.AND)

# Get filtered objects
filtered = SomeModel.objects.filter(filter_query)

您可以在 filter_query 中添加任意数量的过滤器,如果没有添加任何过滤器,它将返回模型的所有对象。

【讨论】:

【参考方案3】:

用你想要的颜色构建你的元组,然后在查询中使用__in

另外,我已经在这里放了字符串,但如果你还没有这样做,我建议对这样的事情使用枚举(除非颜色是用户以某种方式定义的)。

# this would be set from incoming checkbox values, and may be empty:
colours_to_filter = ('red', 'blue', 'green')
materials_to_filter = ()

query = SomeModel.objects.all()
if colours_to_filter:
    query = query.filter(colour__in=colours_to_filter)

if materials_to_filter:
    query = query.filter(material__in=materials_to_filter)

【讨论】:

如何将复选框连接到过滤器?如果用户不想选择颜色(这对他来说并不重要)怎么办? 如果您使用“纯”django 执行此操作并且没有 javascript 过滤,那么您将在视图中看到复选框值并可以相应地处理它们。如何处理用于选择的参数取决于您,但一个简单的解决方案可能是如果他们不选择颜色,则根本不使用该过滤器。 我更新了我的答案,让你知道如何处理这个问题......【参考方案4】:

我通常使用query parameters 进行这些过滤。 它基于用户检查过滤是多个值还是无值。

qs = SomeModel.objects.all()

material = request.GET.get("material")
color = request.GET.get("color")

if material:
    qs = qs.fitler(material__in=material)
if color:
    qs = qs.fitler(color__in=color)  

请注意,有一个名为 django-filter 的包。您可以使用此包进行过滤,它非常有用。 你的form 会是这样的:(示例)

<form action="% url 'view_url' %" method="GET">
    <input type="checkbox" name="color" value="RED">
    <input type="checkbox" name="color" value="GREEN">
    <input type="checkbox" name="color" value="BLUE">
    <button type="submit" value="Submit">Submit</button>
</form>

【讨论】:

如何将变量材质和颜色连接到复选框组? 什么意思?用户检查他想要的颜色等,您的过滤将起作用,您的意思是html代码是什么? 我不明白材料和颜色从哪里获取信息。我需要为它创建复选框?或者 django-filter 自己做?或者我需要为每个项目创建表单,并且我所有选中的复选框都将包含在 request.GET 中? 不,您不需要为所有项目创建复选框,您可以使用get 方法为您的页面创建一个表单。每当用户选择一些过滤并提交表单时,您都可以使用request.GET 在您的视图中获取它们。因为你的表单方法是GET所以他们会进入request.GET 例如,如果您的用户检查颜色过滤,那么 color = request.GET.get("color") 将不会是 None,您将使用用户检查过的一种或多种颜色来过滤您的查询 qs = qs.fitler(color__in=color)

以上是关于如何实现多个过滤器 Django?的主要内容,如果未能解决你的问题,请参考以下文章

如何将三个或多个参数传递给自定义模板标签过滤器 django?

如何创建作为多个查询联合的 Django 模型字段,以实现覆盖字段?

在 django 中,我如何过滤或排除多个东西?

如何在搜索栏中按布尔字段过滤 - django

如何使用 Django-filter 过滤多个字段?

如何在 django 的单个视图中显示多个 ForeignKey 过滤项目?