文章目录
django-filters
0 GitHub
1 环境
2 需求
3 起步
3.1 新建一个Django项目
3.2 settings.py
3.3 models.py
4 django REST框架简单的过滤
4.1 没有使用过滤
4.2 加入过滤器
5 跨表过滤
6 区间过滤
7 跨表后区间过滤
7.1 格式
django-filters
0 GitHub
https://github.com/Coxhuang/django-DjangoFilterBackend.git
1
1 环境
Django2.0.7
djangorestframework3.8.2
django-filter==2.0.0
1
2
3
2 需求
获取某些数据时,需要按某些字段过滤
过滤时,有些的字段是 “跨表” 的字段,该如何处理
过滤时,有些字段是 “区间” 字段(比如时间),该如何处理
过滤时,有些字段是 “跨表” 后的 “区间” 字段,又该如何处理
3 起步
3.1 新建一个Django项目
.
├── app
│ ├── init.py
│ ├── admin.py
│ ├── apps.py
│ ├── filters.py # 添加新文件
│ ├── migrations
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
├── djangofilters
│ ├── init.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
└── templates
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
3.2 settings.py
INSTALLED_APPS = [
...
'rest_framework',
'django_filters',
'app',
]
1
2
3
4
5
6
3.3 models.py
from django.db import models
class Teacher(models.Model):
"""老师表"""
name = models.CharField(verbose_name="老师姓名",max_length=16)
class Student(models.Model):
"""学生表"""
tea = models.ForeignKey(Teacher,on_delete=models.DO_NOTHING,verbose_name="老师")
name = models.CharField(verbose_name="学生姓名",max_length=16)
1
2
3
4
5
6
7
8
9
4 django REST框架简单的过滤
4.1 没有使用过滤
class getUserListSerializer(DynamicFieldsMixin,serializers.ModelSerializer):
teaname = serializers.CharField(label="老师姓名",source="tea.name")
class Meta:
model = models.Student
fields = ["id","name","teaname",]
class getUserListView(mixins.ListModelMixin,GenericViewSet):
queryset = models.Student.objects.all()
serializer_class = getUserListSerializer
1
2
3
4
5
6
7
8
4.2 加入过滤器
filters.py
import django_filters
from app import models
class getUserListFilter(django_filters.rest_framework.FilterSet):
class Meta:
model = models.Student
fields = ["name",]
1
2
3
4
5
6
7
views.py
...
from django_filters import rest_framework
from app.filters import getUserListFilter
class getUserListView(mixins.ListModelMixin,GenericViewSet):
...
filter_backends = (rest_framework.DjangoFilterBackend,)
filter_class = getUserListFilter
1
2
3
4
5
6
7
8
5 跨表过滤
需求:根据老师的名字过滤
class getUserListFilter(django_filters.rest_framework.FilterSet):
teaname = django_filters.CharFilter(field_name='tea__name', label="老师姓名") # 跨表操作
class Meta:
model = models.Student
fields = ["name","teaname",]
1
2
3
4
5
6 区间过滤
新增字段createDate(用户创建时间)
createDate = models.DateTimeField(verbose_name="用户创建时间",auto_now_add=True)
1
filters.py
class getUserListFilter(django_filters.rest_framework.FilterSet):
teaname = django_filters.CharFilter(field_name='tea__name', label="老师姓名")
RegDate = django_filters.DateFromToRangeFilter(field_name='createDate', lookup_expr='gte', label='注册时间') # 区间过滤
class Meta:
model = models.Student
fields = ["name","teaname","RegDate",]
1
2
3
4
5
6
注意 : 在url的参数中,原来我们在filters.py中定义的变量是 “RegDate”,到了url中变成了 “RegDate_after” 和 “RegDate_before”,这是框架给我设定好的区间变量,直接使用就行
more : 更多关键词,请参考文档
7 跨表后区间过滤
需求:学生老师的薪资范围过滤
新增字段salary(老师薪资)
filters.py
class getUserListFilter(django_filters.rest_framework.FilterSet):
teaname = django_filters.CharFilter(field_name='tea__name', label="老师姓名")
RegDate = django_filters.DateFromToRangeFilter(field_name='createDate', lookup_expr='gte', label='注册时间')
salary = django_filters.RangeFilter(method='salary_filter', label='薪资',)
class Meta:
model = models.Student
fields = ["name","teaname","RegDate","salary"]
def salary_filter(self, queryset, name, value):
return queryset.filter(Q(tea__salary__gte = int(value.start)) &
Q(tea__salary__lte = int(value.stop)))
1
2
3
4
5
6
7
8
9
10
11
12
7.1 格式
声明
salary = django_filters.RangeFilter(method='salary_filter', label='薪资',)
1
函数
def salary_filter(self, queryset, name, value):
return queryset.filter(Q(tea__salary__gte = int(value.start)) &
Q(tea__salary__lte = int(value.stop)))
1
2
3
细节
函数名必须是 method 的值
如果是区间,可以使用django_filters.RangeFilter,如果不是区间可以使用其他
重写函数时,里面的参数不会自动补全
坑
使用Q时,一定不能使用or / and,只能使用 | &
return 的数值,如果使用queryset.filter(xxx).filter(xxx),那么返回的结果是所有过滤的交集,如果每个自定义函数都返回自己过滤的数据(例如,models.Student.objects.filter().filter()),那么过滤的结果是所有符合条件的并集
value的正确使用,value.start对应的是url中的min(salary_min),value.stop对应url的max(salary_max)
————————————————
版权声明:本文为CSDN博主「Coxhuang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Coxhuang/article/details/86548197