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_fields
,filterset_fields
为一个列表或元祖,该字段中的元素为模型类对应的字段,然后在视图的url里面即可get传参查找
-- 需要DjangoFilterBackend
支持和django_filter
支持
通用搜索
- 在试图类定义属性
search_fields
,search_fields
为一个列表或元祖,该字段中的元素为模型类对应的字段
- 在url中使用关键字
search
中查找,即可找到所有search_fields
匹配到的内容,关键字search
字段可被定义的SEARCH_PARAM
属性覆盖
--需要SearchFilter
支持
--注意: search可支持扩表查询如user__details__name
,但是search_fields里面的内容最终指向的都应该是字符串类型