在 Django REST Framework 中自定义过滤器
先决条件:在 API 中添加过滤 - Django REST 框架 [lin 需要发布的文章]
Django 过滤器有助于过滤查询集,以根据分配给过滤器字段的值检索相关结果。但是,如果用户想要检索给定范围内的详细信息怎么办。例如,用户需要根据价格范围获取机器人的详细信息。自定义过滤器的必要性来了。让我们创建一个自定义过滤器并将其应用于机器人模型,以便用户可以通过提供机器人类别名称、制造商名称、货币、制造日期范围和/或价格范围来检索机器人详细信息。
我们将创建一个名为RobotFilter类的新类,它是django_filters.FilterSet类的子类。让我们声明进口
Python3
from django_filters import FilterSet, AllValuesFilter
from django_filters import DateTimeFilter, NumberFilter
Python3
class RobotFilter(FilterSet):
from_manufacturing_date = DateTimeFilter(field_name='manufacturing_date',
lookup_expr='gte')
to_manufacturing_date = DateTimeFilter(field_name='manufacturing_date',
lookup_expr='lte')
min_price = NumberFilter(field_name='price', lookup_expr='gte')
max_price = NumberFilter(field_name='price', lookup_expr='lte')
robotcategory_name = AllValuesFilter(field_name='robot_category__name')
manufacturer_name = AllValuesFilter(field_name='manufacturer__name')
class Meta:
model = Robot
fields = (
'name',
'currency',
'from_manufacturing_date',
'to_manufacturing_date',
'min_price',
'max_price',
'robotcategory_name',
'manufacturer_name',
)
Python3
class RobotList(generics.ListCreateAPIView):
queryset = Robot.objects.all()
serializer_class = RobotSerializer
name = 'robot-list'
# customized filter class
filter_class = RobotFilter
search_fields = (
'^name',
)
ordering_fields = (
'price',
)
现在,您可以在 RobotList 类之前添加以下代码。
蟒蛇3
class RobotFilter(FilterSet):
from_manufacturing_date = DateTimeFilter(field_name='manufacturing_date',
lookup_expr='gte')
to_manufacturing_date = DateTimeFilter(field_name='manufacturing_date',
lookup_expr='lte')
min_price = NumberFilter(field_name='price', lookup_expr='gte')
max_price = NumberFilter(field_name='price', lookup_expr='lte')
robotcategory_name = AllValuesFilter(field_name='robot_category__name')
manufacturer_name = AllValuesFilter(field_name='manufacturer__name')
class Meta:
model = Robot
fields = (
'name',
'currency',
'from_manufacturing_date',
'to_manufacturing_date',
'min_price',
'max_price',
'robotcategory_name',
'manufacturer_name',
)
我们来看看 RobotFilter 类中声明的属性。
- from_manufacturing_date
- 到_制造日期
- 最低价格
- 最大价格
- 机器人类别名称
- 生产商名称
from_manufacturing_date:它是一个django_filters.DateTimeFilter实例属性,用于过滤manufacturing_date 值大于或等于指定DateTime 值的机器人。在 DateTimeFilter 中,有两个名为field_name和lookup_expr 的参数。 field_name 具有制造日期(用于过滤),并且“gte”(大于或等于)应用于 lookup_expr。
to_manufacturing_date:它是一个django_filters.DateTimeFilter实例属性,用于过滤manufacturing_date 值小于或等于指定DateTime 值的机器人。在 DateTimeFilter 中,有两个名为field_name和lookup_expr 的参数。在field_name 中,我们提到了制造日期,而'lte'(小于或等于)应用于lookup_expr。
min_price:是django_filters.NumberFilter实例属性,用于过滤价格值大于或等于指定价格值的机器人。
max_price:它是一个django_filters.NumberFilter实例属性,用于过滤价格值小于或等于指定价格值的机器人。
robotscategory_name:它是一个django_filters.AllValuesFilter实例属性,用于过滤机器人类别名称与指定字符串值匹配的机器人。您可以注意到,在提供给field_name的值中,robot_category 和 name 之间有一个双下划线 (__)。 field_name 使用 Django 双下划线将其读取为 RobotCategory 模型的名称字段。这有助于根据机器人类别名称而不是其 pk id 检索机器人的详细信息。
制造商名称:它是一个django_filters.AllValuesFilter实例属性,用于过滤制造商名称与指定字符串值匹配的机器人。 field_name 使用 Django 双下划线读取值 'manufacturer__name' 作为制造商模型的名称字段。这有助于根据制造商名称而不是其 pk id 检索机器人的详细信息。
RobotFilter类还定义了一个Meta内部类。这个类有两个属性model和fields 。模型属性指定要过滤的模型(机器人)。而且, fields 属性包含字段名称和过滤器名称(作为字符串元组)以包含在上述模型(机器人)的过滤器中。
让我们在RobotList类中使用RobotFilter类。代码如下
蟒蛇3
class RobotList(generics.ListCreateAPIView):
queryset = Robot.objects.all()
serializer_class = RobotSerializer
name = 'robot-list'
# customized filter class
filter_class = RobotFilter
search_fields = (
'^name',
)
ordering_fields = (
'price',
)
让我们在制造日期内过滤机器人。 HTTPie 命令是
http “:8000/robot/?from_manufacturing_date=2019-10-01&to_manufacturing_date=2020-03-01”
输出:
让我们根据机器人类别名称和制造商名称过滤机器人。 HTTPie 命令如下
http “:8000/robot/?robotcategory_name=Articulated Robots&manufacturer_name=Fanuc”
输出:
让我们根据价格范围过滤机器人。 HTTPie 命令是
http “:8000/robot/?min_price=10000&max_price=20000¤cy=USD”
输出:
让我们使用可浏览的 API 功能过滤机器人。您可以浏览以下 URL 并单击过滤器按钮。
http://127.0.0.1:8000/robot/
您可以填充值以针对机器人进行过滤。下面分享截图
单击提交按钮后,您将获得过滤后的结果。下面分享截图