django-filters跨表过滤

摘要:
文章目录django过滤器#0GitHub#1环境#2需求#3开始#3.1创建新的django项目#3.2settings。py#3.3型号。py#4简单的django REST框架过滤#4.1不使用过滤#4.2添加过滤器#5跨表过滤#6间隔过滤#7跨表间隔过滤#7.1格式化django过滤器#0GitHubhttps://github.com/Coxhuang/dja
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/DateFilter(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
  • 细节
  1. 函数名必须是 method 的值
  2. 如果是区间,可以使用django_filters.RangeFilter,如果不是区间可以使用其他
  3. 重写函数时,里面的参数不会自动补全
  1. 使用Q时,一定不能使用or / and,只能使用 | &
  2. return 的数值,如果使用queryset.filter(xxx).filter(xxx),那么返回的结果是所有过滤的交集,如果每个自定义函数都返回自己过滤的数据(例如,models.Student.objects.filter().filter()),那么过滤的结果是所有符合条件的并集
  3. value的正确使用,value.start对应的是url中的min(salary_min),value.stop对应url的max(salary_max)
    在这里插入图片描述

在这里插入图片描述

免责声明:文章转载自《django-filters跨表过滤》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇DGL学习(一):使用DGL跑一个最简单的GCNWinForm控件的简单打印方法下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Django cookie加密cryptography

#导包 生成密钥的第三方库 from cryptography.fernet importFernet #密钥 获取密钥#cipher_key = Fernet.generate_key() cipher_key = 'Anmj6guBpUGLJPSmOIrsCBabcsjbdAbdnJDE2pZfmL4=' #定义加密方法 defmy_encode(...

Django项目:CMDB(服务器硬件资产自动采集系统)--11--07CMDB文件模式测试采集硬件数据

1 #settings.py 2 # ————————01CMDB获取服务器基本信息———————— 3 import os 4 5 BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))##当前路径 6 7 # 采集资产的方式,选项有:a...

python测试开发django(10)--models设置主键primary_key

前言 django的models新增数据库表时,如果不设置主键,会默认新增一个id为主键,如果我们想自己设置一个字段为主键,需加个参数primary_key=True 默认id主键 新增一张用户表,表名为account,字段user_name,pwd,mail都是字符串类型,设计如下; #models.py from django.db import mo...

django 解决白名单

1. settings WHITE_REGEX_URL_LIST = [ "/register/", "/send/sms/", "/login/", "/image/code/", "/index/", ] 2. 中间件 from django.utils.deprecation import Middleware...

Django微信小程序后台开发教程

本文链接:https://blog.csdn.net/qq_43467898/article/details/83187698Django微信小程序后台开发教程1 申请小程序,创建hello world小程序2 添加交互框和按钮3 在服务器配置hello django4 实现计算器接口5 配置服务器将后端与微信小程序连接5.1 uwsgi配置5.2 htt...

Django中的缓存

django内置了缓存框架,并提供了几种常用的缓存: 1、基于Memcached缓存 2、使用数据库进行缓存 3、使用文件系统进行缓存 4、使用本地内存进行缓存 5、提供缓存扩展接口 缓存配置 数据库缓存 1、创建缓存表 python manage.py createcachetable [tablename] 2、缓存配置 CACHES = { 'def...