django-filter详解

过滤组件django-filter

官方文档:https://django-filter.readthedocs.io/en/main/

1 安装#

pip install django-filter

在django配置文件中注册app

INSTALLED_APPS = [
    ...
    'django_filters',  # 需要注册应用,
]

环境需求:

  • Python: 3.6, 3.7, 3.8
  • Django: 2.2, 3.1, 3.2
  • DRF: 3.10+

2 使用#

给出一个模型表:

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    description = models.TextField()
    release_date = models.DateField()
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)

模型表有很多字段,我们想按照价格和日期排序,可以这样做

import django_filters   # 导入模块

class ProductFilter(django_filters.FilterSet):
    name = django_filters.CharFilter(lookup_expr='iexact')

    class Meta:
        model = Product
        fields = ['price', 'release_date']

django-filter支持跨表操作,也可以使用双下划线查询,这样会使过滤类显得很冗长,但是保持了最大的自定义程度:

class ProductFilter(django_filters.FilterSet):
    price = django_filters.NumberFilter()
    price__gt = django_filters.NumberFilter(field_name='price', lookup_expr='gt')
    price__lt = django_filters.NumberFilter(field_name='price', lookup_expr='lt')

    release_year = django_filters.NumberFilter(field_name='release_date', lookup_expr='year')
    release_year__gt = django_filters.NumberFilter(field_name='release_date', lookup_expr='year__gt')
    release_year__lt = django_filters.NumberFilter(field_name='release_date', lookup_expr='year__lt')

    manufacturer__name = django_filters.CharFilter(lookup_expr='icontains')

    class Meta:
        model = Product
        fields = ['price', 'release_date', 'manufacturer']

过滤器有两个主要参数:

  • field_name:字段名称,你可以使用django中的双下划线查询语法来使用
  • lookup_expr:过滤时的过滤条件,支持双下划线语法

有关双下划线查询,详见这里

字段field_name和lookup_expr一起表示一个完整的Django查找表达式。比如price__gt = django_filters.NumberFilter(field_name='price', lookup_expr='gt')定义之后,浏览器get请求携带参数price__gt=10,就会根据price字段过滤出符合条件价格大于10的数据。

在Meta类中,model指定要过滤的模型表,fields指定通过哪些字段来过滤。此外,可以使用字典为每个字段指定多个查找表达式:

import django_filters

class ProductFilter(django_filters.FilterSet):
    class Meta:
        model = Product
        fields = {
            'price': ['lt', 'gt'],
            'release_date': ['exact', 'year__gt'],
        }

如果包含外键字段,同样可以使用双下划线语法:

class ProductFilter(django_filters.FilterSet):
    class Meta:
        model = Product
        fields = ['manufacturer__country']

3 drf中使用#

在drf中使用过滤:

from django_filters import rest_framework as filters
# 导入并继承FilterSet类
class ProductFilter(filters.FilterSet):
    ...

你的视图类还需要将DjangoFilterBackend添加到filter_backend中(局部配置)

from django_filters import rest_framework as filters

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (filters.DjangoFilterBackend,) # 配置filter_backends
    filterset_fields = ('category', 'in_stock')

全局配置:

REST_FRAMEWORK = { # 全局配置
    ...
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
    ),
}

要使用FilterSet过滤,需要将其添加到视图类的filterset_class参数中。

from rest_framework import generics
from django_filters import rest_framework as filters
from myapp import Product

# 定义过滤类
class ProductFilter(filters.FilterSet):
    min_price = filters.NumberFilter(field_name="price", lookup_expr='gte')
    max_price = filters.NumberFilter(field_name="price", lookup_expr='lte')

    class Meta:
        model = Product
        fields = ['category', 'in_stock']  # 在Meta中指定过滤哪些字段


class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = ProductFilter   # 在filterset_class中,指定要使用的过滤类

由于支持双下划线语法,就可以在过滤类中创建区间过滤。比如ProductFilter中可以定义min_price和max_price,前端传入最小价格和最大价格就可以过滤出相应字段。

posted @   yyyz  阅读(4364)  评论(0编辑  收藏  举报
编辑推荐:
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
  1. 1 童话镇 陈一发儿
  2. 2 发如雪 周杰伦
  3. 3 小棋童 双笙
  4. 4 说书人 暗杠/寅子
  5. 5 有何不可 许嵩
  6. 6 泡沫 G.E.M.邓紫棋
  7. 7 有何不可 许嵩
  8. 8 Clsr (Aash Mehta Flip) The Chainsmokers,Aash Mehta,Halsey
  9. 9 起风了 吴青峰
  10. 10 燕归巢 许嵩
  11. 11 光年之外 G.E.M.邓紫棋
  12. 12 烟火里的尘埃 华晨宇
  13. 13 淋雨一直走 张韶涵
  14. 14 牵丝戏 银临,Aki阿杰
  15. 15 Somebody That I Used To Know Gotye,Kimbra
  16. 16 幻灯花 (feat. アリレム) アリレム
  17. 17 SOLO JENNIE
  18. 18 错位时空 艾辰
  19. 19 可可托海的牧羊人 王琪
  20. 20 Black Flies Ben Howard
起风了 - 吴青峰
00:00 / 00:00
An audio error has occurred, player will skip forward in 2 seconds.
点击右上角即可分享
微信分享提示
主题色彩