from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
price = models.DecimalField(max_digits=5, decimal_places=2)
description = models.TextField()
release_date = models.DateField()
manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
django
传统过滤查询集方式
Product.objects.filter(name__icontains='小明')
Product.objects.filter(release_date__gt=date(2023, 2, 12))
Product.objects.filter(price__gt=10)
直接使用
django可以直接使用获取queryset
queryset = ProductFilter(Product.objects.all()).queryset
搭配drf
drf
当然搭配django-filters
更加优雅。而不是在get_queryset
方法中书写传统的查询方法。默认每个字段的值相等
。更复杂的过滤需要定义FilterSet
。
import django_filters
class ProductFilter(django_filters.FilterSet):
# 模糊搜索name字段
name = django_filters.CharFilter(lookup_expr='contains')
price_gt = django_filters.NumberFilter(lookup_expr='gte', field_name='price')
class Meta:
model = Product
fields = ['price', 'release_date']
书写形式类似rest_framework
序列化器。
核心参数
lookup_expr
指代Django QuerySet语法
。
field_name
筛选的模型字段和模型字段对应。
集成drf
# settings.py
INSTALLED_APPS = [
...
'rest_framework',
'django_filters',
]
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
# 全局配置
'django_filters.rest_framework.DjangoFilterBackend',
...
),
}
# views
from rest_framework import serializers
from rest_framework.generics import GenericAPIView, ListAPIView
import django_filters
class ProductSerializer(serializers.ModelSerializer):
class Meta:
model = Product
fields = '__all__'
class ProductGenericAPIView(ListAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
# 使用 filterset_class 指定 FilterSet 默认只有相等或者前端书写类似 django查询表达式样式。前端是不能接受而且不易维 护
filterset_class = ProductFilter
# 另外,还可以指定filterset_fields指定查询的某些字段
filterset_fields = ('name', 'price')
前端请求方式
xxx/?name=xxx&price=xxx
pip install django-filter
当然,以上放到一个py文件中是为了能够能够更快速得到结果。每个模块下,序列化器应放到serializers.py
,过滤器放到filters.py
下。