如何在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、请求看效果

 问题完美解决~

 



posted on 2020-04-11 17:42  猪也会飞  阅读(628)  评论(0)    收藏  举报

导航