在Django REST框架中定制过滤器
Django的过滤器便于对查询集进行过滤,以根据分配给过滤器字段的值来检索相关的结果。但是,如果用户想在一个给定的范围内检索细节,怎么办?例如,用户需要根据价格范围来获取机器人的细节。这时就需要定制过滤器了。让我们为机器人模型创建并应用一个自定义的过滤器,这样用户就可以通过提供机器人类别名称、制造商名称、货币、生产日期范围和/或价格范围来检索机器人的详细信息。
我们将创建一个名为RobotFilter的新类,它是django_filters.FilterSet类的一个子类。让我们声明一下进口
from django_filters import FilterSet, AllValuesFilter
from django_filters import DateTimeFilter, NumberFilter
现在,你可以在RobotList类之前添加以下代码。
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
- to_manufacturing_date
- min_price
- max_price
- robotcategory_name
- manufacturer_name
from_manufacturing_date:它是一个django_filters.DateTimeFilter实例属性,用于过滤制造日期值大于或等于指定DateTime值的机器人。在DateTimeFilter中,有两个参数名为field_name和lookup_expr。field_name有制造日期(用于过滤),’gte’(大于或等于)被应用于lookup_expr。
to_manufacturing_date:这是一个django_filters.DateTimeFilter实例属性,用于过滤制造日期值小于或等于指定DateTime值的机器人。在DateTimeFilter中,有两个参数名为field_name和lookup_expr。在field_name中,我们提到了manufacture_date,而’lte’(小于或等于)被应用于lookup_expr。
min_price:它是一个django_filters.NumberFilter实例属性,用于过滤价格值大于或等于指定价格值的机器人。
max_price:它是一个django_filters.NumberFilter实例属性,用于过滤价格值小于或等于指定价格值的机器人。
robotcategory_name:这是一个django_filters.AllValuesFilter实例属性,用于过滤机器人类别名称与指定字符串值相符的机器人。你可以注意到,在提供给field_name的值中有一个双下划线(__),在robot_category和name之间。field_name使用Django的双下划线,将其作为RobotCategory模型的名称字段来读取。这有助于根据机器人类别名称而不是其pk id来检索机器人的详细信息。
manufacturer_name:它是一个django_filters.AllValuesFilter实例属性,用于过滤制造商名称与指定字符串值相匹配的机器人。field_name使用Django的双下划线来读取值’manufacturer__name’作为制造商模型的名称字段。这有助于根据制造商名称而不是其pk id来检索机器人的详细信息。
RobotFilter类还定义了一个Meta内类。这个类有两个属性model和fields。模型属性指定要过滤的模型(机器人)。而且,字段属性持有字段名和过滤器名称(作为一个字符串的元组),以包括在所述模型(机器人)的过滤器中。
让我们在我们的RobotList类中使用RobotFilter类。代码如下
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/
你可以填充数值来过滤机器人。分享下面的截图
点击提交按钮后,你将得到过滤后的结果。分享下面的屏幕截图