django-filters跨表过滤
2021/4/26 18:28:03
本文主要是介绍django-filters跨表过滤,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 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 环境
Django==2.0.7 djangorestframework==3.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)
这篇关于django-filters跨表过滤的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-09-05MongoDB入门:快速掌握NoSQL数据库基础
- 2024-08-28go 项目中怎么打印调试-icode9专业技术文章分享
- 2024-08-21swoole未来的发展前景与golang对比哪个更好-icode9专业技术文章分享
- 2024-08-16goland 已经下了中文插件了, 怎么设置成中文-icode9专业技术文章分享
- 2024-07-26使用 SendGrid 的 Go 客户端库能同时给多个邮箱发吗-icode9专业技术文章分享
- 2024-07-26使用 SendGrid 的 Go 客户端库时怎么设置header 和 标签tag 呢-icode9专业技术文章分享
- 2024-07-26SendGrid 对邮件的类别(Categories)和标签的数量有限制吗?-icode9专业技术文章分享
- 2024-07-17课程推荐《高性能GO企业级APM监控系统实战》
- 2024-06-26解决google chrome helper 内存占用较高!
- 2024-04-01got an unexpected keyword argument