drf - 筛选组件DjangoFilterBackend
时间:2019-09-15
本文章向大家介绍drf - 筛选组件DjangoFilterBackend,主要包括drf - 筛选组件DjangoFilterBackend使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
数据准备
model.py文件
定义两个表Car表和Brand表,其中Car中的brand字段外键关联Brand表
from django.db import models
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False)
create_time = models.DateTimeField(auto_now_add=True)
class Meta:
abstract = True
class Car(BaseModel):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
brand = models.ForeignKey('Brand', db_constraint=False, on_delete=models.DO_NOTHING, related_name='cars')
@property
def brand_name(self):
return self.brand.name
class Meta:
db_table = 'old_boy_car'
verbose_name = '汽车'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Brand(BaseModel):
name = models.CharField(max_length=32)
class Meta:
db_table = 'old_boy_brand'
verbose_name = '品牌'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
新建的serializer.py文件
brand字段只参与反序列化,brand_name只参与序列化
from rest_framework.serializers import ModelSerializer
from . import models
class CarModelSerializer(ModelSerializer):
class Meta:
model = models.Car
fields = ('name','price','brand','brand_name')
extra_kwargs = {
"brand":{
'write_only':True
},
'brand_name':{
'read_only':True
},
}
分类筛选 filter_fields
views.py文件
from rest_framework.viewsets import ModelViewSet
from . import models, serializer
from django_filters.rest_framework import DjangoFilterBackend
class CarModelViewSet(ModelViewSet):
queryset = models.Car.objects.filter(is_delete=False)
serializer_class = serializer.CarModelSerializer
filter_backends = [DjangoFilterBackend]
# 分类: 一般都是可以分组的字段
filter_fields = ['brand']
# 按品牌brand分类,url链接:/car/?brand=1
区间筛选 filter_class
新建的 filterset.py
max_price与min_price是用于参与区间分类,不写也可以仅做分类同 filter_fields效果一样
from django_filters import FilterSet,filters
from . import models
class CarFilterSet(FilterSet):
max_price = filters.NumberFilter(field_name='price',lookup_expr='lte')
min_price = filters.NumberFilter(field_name='price',lookup_expr='gte')
class Meta:
model = models.Car
# brand 还是实现分类
fields = ['brand','max_price','min_price']
views.py文件
from rest_framework.viewsets import ModelViewSet
from . import models, serializer
from django_filters.rest_framework import DjangoFilterBackend
from .filterset import CarFilterSet
class CarModelViewSet(ModelViewSet):
queryset = models.Car.objects.filter(is_delete=False)
serializer_class = serializer.CarModelSerializer
filter_backends = [DjangoFilterBackend]
filter_class = CarFilterSet
# url链接:/car/?max_price=100 价格不超过100
# url链接:/car/?min_price=10 价格不低于10
# url链接:/car/?brand=1&min_price=10&max_price=100 品牌brand为1且价格在[10,100]内的汽车
DjangoFilterBackend部分源码解析
1. 在DjangoFilterBackend组件中先调用filter_queryset方法中
def filter_queryset(self, request, queryset, view):
filterset = self.get_filterset(request, queryset, view) # 获取筛选条件
# 如果filterset为None,表示没有筛选条件
if filterset is None:
return queryset
# 无效的筛选条件处理
if not filterset.is_valid() and self.raise_exception:
raise utils.translate_validation(filterset.errors)
return filterset.qs
2. 调用get_filterset方法获取filterset
def get_filterset(self, request, queryset, view):
filterset_class = self.get_filterset_class(view, queryset) # 获取筛选类
if filterset_class is None:
return None
kwargs = self.get_filterset_kwargs(request, queryset, view)
return filterset_class(**kwargs)
3.调用get_filterset_class方法获取filterset_class
def get_filterset_class(self, view, queryset=None):
"""
Return the `FilterSet` class used to filter the queryset.
"""
filterset_class = getattr(view, 'filterset_class', None)
filterset_fields = getattr(view, 'filterset_fields', None)
# 将filter_class映射给filterset_class
if filterset_class is None and hasattr(view, 'filter_class'):
utils.deprecate(
"`%s.filter_class` attribute should be renamed `filterset_class`."
% view.__class__.__name__)
filterset_class = getattr(view, 'filter_class', None)
# 将filter_fields映射给filterset_fields
if filterset_fields is None and hasattr(view, 'filter_fields'):
utils.deprecate(
"`%s.filter_fields` attribute should be renamed `filterset_fields`."
% view.__class__.__name__)
filterset_fields = getattr(view, 'filter_fields', None)
# 有filterset_class时执行,filterset_class定义的是一个类
if filterset_class:
filterset_model = filterset_class._meta.model
# FilterSets do not need to specify a Meta class
if filterset_model and queryset is not None:
assert issubclass(queryset.model, filterset_model), \
'FilterSet model %s does not match queryset model %s' % \
(filterset_model, queryset.model)
return filterset_class
# 有filterset_fields时执行
if filterset_fields and queryset is not None:
MetaBase = getattr(self.filterset_base, 'Meta', object)
class AutoFilterSet(self.filterset_base):
class Meta(MetaBase):
model = queryset.model
fields = filterset_fields
return AutoFilterSet
return None
原文地址:https://www.cnblogs.com/863652104kai/p/11522191.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- java编程思想第四版第七章总结
- OpenVPN原理及部署使用
- 04 . Jenkins部署Java项目
- java编程思想第四版第七章习题
- 03 . Jenkins构建之代码扫描
- mysql提示Packet for query is too large (1142 > 1024)解决方案
- Kubernetes 1.19.0——deployment(1)
- 02 . Jeknins简介部署及自动化部署PHP代码
- java编程思想第四版第八章习题
- java编程思想第四版第八章总结
- ESP32从网络获取天气OLED显示(附源码)
- 02 . Zabbix配置监控项及聚合图形
- 01 . GitLab简介及环境部署
- 03 . Prometheus监控容器和HTTP探针应用及服务发现
- java编程思想第四版第九章习题