Dajngo自带的Django-filter的使用详解

  • 时间:
  • 来源:互联网
  • 文章标签:

目标:利用django自带的filte实现精准、模糊查询 (实战代码)

步骤:

1、安装第三方库

pip  install  django-filter

2、配置setting

# 注册app
INSTALLED_APPS = [
    'rest_framework',
    'django_filters',
    .......
]

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

3、定义模型

# coding:utf-8
from django.db import models

class Teacher(models.Model):
    """老师表"""
    name = models.CharField(verbose_name="老师姓名", max_length=16)
    motto = models.CharField(verbose_name="格言", max_length=32)

class Student(models.Model):
    """学生表"""
    tea = models.ForeignKey(Teacher, on_delete=models.DO_NOTHING, verbose_name="老师")
    name = models.CharField(verbose_name="学生姓名", max_length=16)
    add_time = models.DateField(verbose_name='添加日期', auto_now_add=True)
    age = models.IntegerField(verbose_name='年龄')

4、新建filter文件,添加filter配置

# coding:utf-8
import django_filters
from django_filters import rest_framework as filters
#coding:utf-8
from api import models


class ProductSourceNameListFilter(django_filters.CharFilter):
    def filter(self, qs, value):
        value = list(filter(None, value.split(",")))
        return super(ProductSourceNameListFilter, self).filter(qs=qs, value=value)


class getUserListFilter(django_filters.rest_framework.FilterSet):
    '''过滤模型类'''
    # method one
    # tea = ProductSourceNameListFilter(field_name='tea', lookup_expr='in')

    # method two
    tea = filters.CharFilter(method='filter_tea', lookup_expr='in')
    name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')

    #区间过滤
    #method  one
    min_age = django_filters.NumberFilter(field_name='age', lookup_expr='gt')
    max_age = django_filters.NumberFilter(field_name='age', lookup_expr='lt')
    #method two 
    age = filters.NumberFilter(field_name='age', help_text='年龄')
    
    # 时间区间查询 DateFromToRangeFilter

    class Meta:
        model = models.Student
        fields = ['name', 'tea', 'min_age', 'max_age', 'add_time']  # 允许精准查询的字段
        search_fields = ['name', ]  # 允许模糊查询的字段,上面需要定义

    def filter_tea(self, queryset, name, value):
        value_list = list(filter(None, value.split(",")))
        order_ids = models.Student.objects.filter(tea__in=value_list)
        return queryset.filter(id__in=order_ids)

5、定义序列号,新建ser文件。

# coding:utf-8
from rest_framework import serializers

from api import models

class getUserListSerializer(serializers.ModelSerializer):
    '''student模型序列化'''
    # teaname = serializers.CharField(label="老师姓名", source="tea.name")
    # motto = serializers.CharField(label="老师姓名", source="tea.motto")
    # days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = models.Student
        # fields = ["id", "name", "teaname", ]  # 需要系列化的字段
        fields = '__all__'
        depth = 1  # 向下取的深度

    # 方法写法:get_ + 字段
    def get_days_since_joined(self, obj):
        # obj指这个model的对象
        return '%s-24' % obj.name

6、新建views文件,配置views文件。

# coding:utf-8

from django_filters import rest_framework
from rest_framework.viewsets import ModelViewSet

from api import models
from api.utils.filter import getUserListFilter
from api.utils.ser import getUserListSerializer
from rest_framework import filters

# Create your views here.

class getUserListView(ModelViewSet):
    '''View逻辑视图'''
    queryset = models.Student.objects.all()   # 查询所有数据
    serializer_class = getUserListSerializer  # 数据序列化
    filter_backends = (rest_framework.DjangoFilterBackend, filters.SearchFilter,filters.OrderingFilter,)  # 需要用django查询的固定写法
    filter_class = getUserListFilter    # 定义过滤查询
    # 排序的字段
    ordering_fields = ('tea', )

7、配置路由。

    url(r'^test/$', views.getUserListView.as_view({'get': 'list'})),

8、打开postman测试接口。

http://127.0.0.1:8000/api/test/?name=&tea=1,2&add_time=2019-07-10&min_age=&max_age=

9、测试按照tea排序。

http://127.0.0.1:8000/api/test/?name=&tea=&add_time=2019-07-10&min_age=&max_age=&ordering=-tea

tips:

其中如果ordering=-tea表示降序排列,否则为升序排列。

如果 ordering_fields = ('tea', 'id')为多字段排序,可以用,隔开使用多字段排序:ordering=-tea,id

我们可以利用浏览器为我们生成过滤器字段。

本文链接http://www.taodudu.cc/news/show-647641.html