Django-Filter与Django REST Framework集成指南

Django-Filter与Django REST Framework集成指南

django-filter A generic system for filtering Django QuerySets based on user selections django-filter 项目地址: https://gitcode.com/gh_mirrors/dj/django-filter

概述

Django-Filter是一个强大的过滤库,专门为Django项目设计。当它与Django REST Framework (DRF)结合使用时,可以极大地增强API的过滤功能。本文将详细介绍如何将Django-Filter集成到DRF项目中,以及如何充分利用其提供的各种功能。

快速开始

要在DRF中使用Django-Filter,首先需要调整导入路径。不再从django_filters导入,而是从rest_framework子包导入。

from django_filters import rest_framework as filters

class ProductFilter(filters.FilterSet):
    ...

视图类还需要将DjangoFilterBackend添加到filter_backends中。

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

如果想默认使用django-filter后端,可以将其添加到DEFAULT_FILTER_BACKENDS设置中。

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': (
        'django_filters.rest_framework.DjangoFilterBackend',
        # 其他后端...
    ),
}

使用FilterSet

通过filterset_class添加FilterSet

要为视图启用FilterSet过滤,需要在视图类中添加filterset_class参数。

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']

class ProductList(generics.ListAPIView):
    queryset = Product.objects.all()
    serializer_class = ProductSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filterset_class = ProductFilter

使用filterset_fields快捷方式

如果不想创建完整的FilterSet,可以使用filterset_fields快捷方式。这相当于创建一个只包含Meta.fields的FilterSet。

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

注意:filterset_fieldsfilterset_class不能同时使用。

高级定制

覆盖FilterSet创建

可以通过覆盖后端类上的以下方法来定制FilterSet的创建:

  1. .get_filterset(self, request, queryset, view)
  2. .get_filterset_class(self, view, queryset=None)
  3. .get_filterset_kwargs(self, request, queryset, view)

这些方法可以针对每个视图单独覆盖,创建独特的后端,也可以用来编写自己的视图类钩子。

class MyFilterBackend(filters.DjangoFilterBackend):
    def get_filterset_kwargs(self, request, queryset, view):
        kwargs = super().get_filterset_kwargs(request, queryset, view)
        
        # 合并视图类提供的filterset kwargs
        if hasattr(view, 'get_filterset_kwargs'):
            kwargs.update(view.get_filterset_kwargs())
            
        return kwargs

class BookFilter(filters.FilterSet):
    def __init__(self, *args, author=None, **kwargs):
        super().__init__(*args, **kwargs)
        # 使用author做一些事情

class BookViewSet(viewsets.ModelViewSet):
    filter_backends = [MyFilterBackend]
    filterset_class = BookFilter

    def get_filterset_kwargs(self):
        return {
            'author': self.get_author(),
        }

界面美化

如果使用DRF的可浏览API或管理API,可以安装django-crispy-forms来增强过滤表单在HTML视图中的呈现效果。它会使用Bootstrap 3 HTML渲染表单。

安装命令:

pip install django-crispy-forms

安装后并将其添加到Django的INSTALLED_APPS中,可浏览API将为DjangoFilterBackend提供一个过滤控件。

DRF特有的FilterSet功能

以下是专门为REST框架FilterSet提供的功能:

  1. BooleanFilter使用API友好的BooleanWidget,它接受小写的true/false
  2. 过滤器生成对日期时间模型字段使用IsoDateTimeFilter
  3. 引发的ValidationError会被重新引发为它们的DRF等效项

最佳实践

  1. 对于简单过滤需求,使用filterset_fields快捷方式
  2. 对于复杂过滤逻辑,创建自定义的FilterSet
  3. 考虑将常用过滤后端设置为默认后端
  4. 对于需要额外上下文或参数的过滤器,覆盖get_filterset_kwargs方法
  5. 在生产环境中,考虑为API文档添加过滤参数说明

通过合理使用Django-Filter与DRF的集成,可以构建出功能强大且灵活的API过滤系统,大大提升API的可用性和用户体验。

django-filter A generic system for filtering Django QuerySets based on user selections django-filter 项目地址: https://gitcode.com/gh_mirrors/dj/django-filter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

董洲锴Blackbird

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值