如何在DRF中使用过滤器
一、准备工作:首先定义好model以及视图类、序列化类相关信息
class Book(models.Model): name = models.CharField(max_length=32) pub_num = models.IntegerField(default=10) salary_num = models.IntegerField(default=100) def __str__(self): return self.name class CheckView(viewsets.GenericViewSet, mixins.ListModelMixin): queryset = models.Book.objects.all() serializer_class = BookSerializer def get(self, request): res = self.serializer_class(self.queryset, many=True) return Response(res.data)class BookSerializer(serializers.ModelSerializer): authors_info = serializers.SerializerMethodField(read_only=True) class BookSerializer(serializers.ModelSerializer): authors_info = serializers.SerializerMethodField(read_only=True) def get_authors_info(self, obj): return [{'id': author.id, 'name': author.name} for author in obj.authors.all()] class Meta: fields = '__all__' model = models.Book
二、重写get_queryset()方法进行过滤数据
1、get_queryset中进行数据过滤
def get_queryset(self): condition = self.request.query_params.get('min_num') queryset = self.queryset if condition: return queryset.filter(pub_num__gt=condition) return queryset
请求发布数量超过15本书的书籍详情,实现数据过滤
![]()

问题:
但是如果过滤条件很多的情况,就需要加入很多的筛选,也就是get_queryset函数需要获取每个参数及其值,然后在查询集进行过滤,比较麻烦
三、使用DjangoFilterBackend实现多条件过滤
1、下载django-filter模块 --- pip install django-filter模块
2、导入模块 from django_filters.rest_framework import DjangoFilterBackend
3、在视图类中添加2个属性
class CheckView(viewsets.GenericViewSet, mixins.ListModelMixin): queryset = models.Book.objects.all() serializer_class = BookSerializer filter_backends = [DjangoFilterBackend] # 使用哪个过滤器类 filter_fields = ('id', 'pub_num') # 过滤的字段
4、在settings.py的INSTALLED_APPS中添加app
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'rest_framework', # DRF html页面 'django_filters' # 过滤 html页面 ]
5、请求 http://127.0.0.1:8000/app01/?id=2&pub_num=

6、得到过滤结果

问题:
如果想要获取出版数大于或者小于某个条件的结果,此方式不支持,当前模式只支持 == 条件
四、自定制过滤类来实现
1、创建filters.py文件
from django_filters import rest_framework as filters from . import models class BookFilter(filters.FilterSet):
# 自定制每个字段的查询筛选条件 name = filters.CharFilter(field_name='name', lookup_expr='icontains') # i表示忽略大小写 pub_num = filters.NumberFilter(field_name='pub_num', lookup_expr='gte') # gte表示大于等于 salary_num = filters.NumberFilter(field_name='salary_num', lookup_expr='lte') class Meta: model = models.Book fields = '__all__'
2、在视图类中添加属性
class CheckView(viewsets.GenericViewSet, mixins.ListModelMixin): queryset = models.Book.objects.all() serializer_class = BookSerializer filter_backends = [DjangoFilterBackend] # filter_fields = ('id', 'pub_num') # 将之前的字段过滤内容注释 filter_class = BookFilter # 使用创建的类
3、请求看效果

问题完美解决~
浙公网安备 33010602011771号