django-filter的基本使用

django-filter 查询

创建model和视图

from django.db import models


# Create your models here.

class Student(models.Model):
    SEX_CHOICES = (
        (0, '女'),
        (1, '男')
    )
    name = models.CharField(max_length=10)
    sex = models.SmallIntegerField(choices=SEX_CHOICES)
    courses = models.ManyToManyField('Course')
    teacher = models.ForeignKey('Teacher', on_delete=models.SET_NULL, null=True)

    def __str__(self):
        return self.name


class Teacher(models.Model):
    name = models.CharField(max_length=10)

    def __str__(self):
        return self.name


class Course(models.Model):
    name = models.CharField(max_length=10)

    def __str__(self):
        return self.name

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.viewsets import ModelViewSet
from . import serializer
from . import models
from . import filter


class StudentView(ModelViewSet):
    queryset = models.Student.objects.all()
    serializer_class = serializer.StudentSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_class = filter.StudentFilter
from django_filters.rest_framework import FilterSet
import django_filters
from . import models


class StudentFilter(FilterSet):
    # 原始查询 + lookup_expr查询表达式
    name = django_filters.CharFilter(field_name='name', lookup_expr='icontains')
    # choice查询
    sex = django_filters.ChoiceFilter(choices=models.Student.SEX_CHOICES)
    # 自定义choice value查询
    sex_display = django_filters.CharFilter(method='get_sex_display')

    # 跨表查询
    teacher = django_filters.CharFilter(field_name='teacher__name')

    class Meta:
        model = models.Student
        fields = '__all__'

    def get_sex_display(self, queryset, name, value):
        # print(self.qs)
        item = {i[1]: i[0] for i in models.Student.SEX_CHOICES}
        sex_value = item.get(value, None)
        if sex_value is not None:
            condition = {'sex': sex_value}
            return queryset.filter(**condition)
        return queryset

定义filterset_fields

  • 在视图类定义属性filterset_fieldsfilterset_fields为一个列表或元祖,该字段中的元素为模型类对应的字段,然后在视图的url里面即可get传参查找
    -- 需要DjangoFilterBackend支持和django_filter支持

通用搜索

  • 在试图类定义属性search_fieldssearch_fields为一个列表或元祖,该字段中的元素为模型类对应的字段
  • 在url中使用关键字search中查找,即可找到所有search_fields匹配到的内容,关键字search字段可被定义的SEARCH_PARAM属性覆盖
    --需要SearchFilter支持
    --注意: search可支持扩表查询如user__details__name,但是search_fields里面的内容最终指向的都应该是字符串类型

详情:https://www.django-rest-framework.org/api-guide/filtering/

原文地址:https://www.cnblogs.com/ivy-blogs/p/11932815.html