Django系列之DRF搜索和过滤

1. model之间关系

python 复制代码
class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=8)
    email = models.CharField(max_length=32)

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    pub_date = models.DateField()
    publish = models.ForeignKey(Publish, on_delete=models.CASCADE, null=True)

2. DRF搜索

在DRF中使用搜索功能,只需要在 viewsets 视图类中定义 filter_backendssearch_fields 即可使用。

filter_backends:后端使用的搜索和过滤类。
search_fields :要执行搜索条件的字段,搜索为模糊查询(要在哪些字段上执行模糊查询,支持多表连表查询)。

对应的URL格式就是这种:http://127.0.0.1:9000/test/publishes/?search=北京

python 复制代码
class PublishModelViewSets(viewsets.ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    filter_backends = (SearchFilter, )
    search_fields = ("name", "city", "book__title")   

3. django-filter简单过滤

安装包:pip install django-filter

使用:在 viewsets 视图类的 filter_backends 属性中追加 DjangoFilterBackend,再添加 filterset_fields 属性即可使用。

filterset_fields:要执行过滤条件的字段,执行的是精准查询。

对应的URL格式就是这种 http://127.0.0.1:9000/test/publishes/?name=GansuEngEduPublisher&city=甘肃

在settings配置文件的app中添加:

python 复制代码
INSTALLED_APPS = [
	...
    'django_filters'
]
python 复制代码
class PublishModelViewSets(viewsets.ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    filter_backends = (SearchFilter, DjangoFilterBackend)
    search_fields = ("name", "city", "book__title")     # 模糊查询
    filterset_fields = ("name", "city")					# 精准查询

filterset_fields 也可以按照自定义的方式过滤。

对应的URL格式就是这种:http://127.0.0.1:9000/test/publishes/?name__icontains=gansueng&city=甘肃

python 复制代码
class PublishModelViewSets(viewsets.ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    filter_backends = (SearchFilter, DjangoFilterBackend)
    search_fields = ("name", "city", "book__title")     # 模糊查询
    filterset_fields = {
        "name": ["icontains"],      # 包含此查询条件,大小写不敏感
        "city": ['exact']           # 完全相等
    }
    

4. django-filter自定义过滤器类和过滤器函数

  • 过滤器中常用的字段类型,这些类型要和模型中对应的字段类型兼容:

    CharFilter 字符串类型
    BooleanFilter 布尔类型
    DateTimeFilter 日期时间类型
    DateFilter 日期类型
    DateRangeFilter 日期范围
    TimeFilter 时间类型
    NumberFilter 数值类型,对应模型中IntegerField, FloatField, DecimalField

  • 字段内参数说明:

    field_name:过滤字段名,对应模型中的字段名
    lookup_expr:查询时所要进行的操作,和ORM中运算符一致
    method:该字段对应的自定义过滤器函数

  • Meta字段使用:

    model:引用的模型,不是字符串
    fields:指明过滤字段,可以是列表,列表中字典可以过滤,默认是判断相等;也可以是字典,字典可以自定义操作。
    exclude:排除字段,不允许使用列表中字典进行过滤

5. django-filter 使用示例

在视图类中添加自定义的过滤类:

python 复制代码
class PublishModelViewSets(viewsets.ModelViewSet):
    queryset = Publish.objects.all()
    serializer_class = PublishSerializer
    filter_backends = (SearchFilter, DjangoFilterBackend)
    search_fields = ("name", "city", "book__title")   
    filter_class = PublishFilter		# 自定义过滤类

在app中新建一个filters.py文件,编写自己的自定义过滤函数,也可以不写,使用默认的 orm 筛选关键字。

python 复制代码
from django_filters import filters, FilterSet
from app01.models import Publish

class PublishFilter(FilterSet):
    pub_city = filters.CharFilter(field_name='city', lookup_expr='exact')
    pub_email = filters.CharFilter(field_name='email', method='filter_email')

    @staticmethod
    def filter_email(queryset, field_name, value):
        """
        出版社邮件以前端传过来的value值结尾的出版社
        :param queryset: 查询到的数据集
        :param field_name: 过滤的字段名
        :param value: 前端传过来的值
        :return: 过滤后的数据集
        """
        print(field_name, value)
        return queryset.filter(**{f"{field_name}__endswith": value})

    class Meta:
        model = Publish     # 模型名
        fields = ["pub_city", "pub_email"]         # 过滤字段

对应的URL格式就是这样:http://127.0.0.1:9000/test/publishes/?pub_city=北京&pub_email=edu

注意:上述的自定义过滤器类和过滤器函数的方式,在 django-filter 的某些版本不适用,会导致无法过滤,获取到的是全集。上述使用的 django-filter 版本为 21.1。

相关推荐
Francek Chen22 分钟前
【大数据存储与管理】分布式数据库HBase:03 HBase数据模型
大数据·数据库·hadoop·分布式·hdfs·hbase
小吴编程之路8 小时前
MySQL 索引核心特性深度解析:从底层原理到实操应用
数据库·mysql
~莫子8 小时前
MySQL集群技术
数据库·mysql
凤山老林8 小时前
SpringBoot 使用 H2 文本数据库构建轻量级应用
java·数据库·spring boot·后端
就不掉头发8 小时前
Linux与数据库进阶
数据库
与衫8 小时前
Gudu SQL Omni 技术深度解析
数据库·sql
wefly20178 小时前
开发者效率神器!jsontop.cn一站式工具集,覆盖开发全流程高频需求
前端·后端·python·django·flask·前端开发工具·后端开发工具
咖啡の猫9 小时前
Redis桌面客户端
数据库·redis·缓存
oradh9 小时前
Oracle 11g数据库软件和数据库静默安装
数据库·oracle
what丶k9 小时前
如何保证 Redis 与 MySQL 数据一致性?后端必备实践指南
数据库·redis·mysql