原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。
DRF应用和管理
【DRF配置管理】Django安装DRF框架并生成openapi风格文档
【DRF配置管理】如何实现JWT身份验证
【DRF配置管理】如何使用序列化:验证码、注册和登录
【DRF配置管理】如何结合ORM实现排序、模糊搜索、范围查询
【DRF配置管理】如何在视图类使用get_objects()
【DRF配置管理】如何实现RBAC页面菜单和按钮权限
【DRF配置管理】如何建立coreapi风格api接口文档
【DRF配置管理】如何建立swagger风格api接口文档
文章目录
一、drf过滤查询
1.针对当前用户进行筛选
from myapp.models import Purchase
from myapp.serializers import PurchaseSerializer
from rest_framework import generics
class PurchaseList(generics.ListAPIView):
serializer_class = PurchaseSerializer
def get_queryset(self):
"""
This view should return a list of all the purchases
for the currently authenticated user.
"""
user = self.request.user
return Purchase.objects.filter(purchaser=user)
2.根据查询参数进行筛选
查询链接:http://example.com/api/purchases?username=denvercoder9
class PurchaseList(generics.ListAPIView):
serializer_class = PurchaseSerializer
def get_queryset(self):
"""
Optionally restricts the returned purchases to a given user,
by filtering against a `username` query parameter in the URL.
"""
queryset = Purchase.objects.all()
username = self.request.query_params.get('username')
if username is not None:
queryset = queryset.filter(purchaser__username=username)
return queryset
如果想使用orm的__gte、__lte这些方法,可以在这里实现(缺陷是都需要重写),具体代码如下:
查询链接:/api/v1/sar/sarpics/?page=1&size=1&ImagingTime__gte=2020-12-22T00%3A00%3A00Z&ImagingTime__lte=2021-06-22T00%3A00%3A00Z
def get_queryset(self):
print('gte', self.request.query_params.get('ImagingTime__gte'))
ImagingTime__gte = self.request.query_params.get('ImagingTime__gte')
ImagingTime__lte = self.request.query_params.get('ImagingTime__lte')
if ImagingTime__gte:
self.queryset = self.queryset.filter(ImagingTime__gte=ImagingTime__gte)
if ImagingTime__lte:
self.queryset = self.queryset.filter(ImagingTime__lte=ImagingTime__lte)
return self.queryset
3.通用筛选-models字段查询
3.1 默认不包含__gte、__lte等条件查询
django_filters需要导入django-filter库,
查询链接:http://example.com/api/products?category=clothing&in_stock=True
import django_filters.rest_framework
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics
from django_filters.rest_framework import DjangoFilterBackend
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [DjangoFilterBackend,]
filterset_fields = ['category', 'in_stock'] # 可指定查询字段,默认无
3.2 实现__gte、__lte等查询
需要自定义FilterSet类,并在视图类中指定filterset_class。(老版本也有指定filter_class参数的,用filterset_class参数filterset_fields就需要禁用,不要同时使用)
filters.py文件
import django_filters
class ProductFilter(django_filters.FilterSet):
name = django_filters.CharFilter(lookup_expr='iexact') # iexact表示精确匹配, 并且忽略大小写
author = django_filters.CharFilter(lookup_expr='icontains') #icontains表示模糊查询(包含),并且忽略大小写
price = django_filters.NumberFilter(look_expr='exact') #exact表示精确匹配
desc = django_filters.CharFilter('description', lookup_expr='contains') #对'description'字段进行操作,不填默认为desc
#price__lte = django_filters.NumberFilter('price', lookup_expr='lte') #lte表示小于
#price__gte = django_filters.NumberFilter('price', look_expr='gte') # gte表示大于
class Meta:
model = Product
fields = ['name', 'author', 'price', 'description']
#fields = {
'price': ['lt', 'gt']
}
view.py文件
import django_filters.rest_framework
from django.contrib.auth.models import User
from myapp.serializers import UserSerializer
from rest_framework import generics
from django_filters.rest_framework import DjangoFilterBackend
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [DjangoFilterBackend,]
# filterset_fields = ['category', 'in_stock']
filterset_class = ProductFilter
4.跨表筛选
class getUserListFilter(django_filters.rest_framework.FilterSet):
teaname = django_filters.CharFilter(field_name='tea__name', label="老师姓名") # 跨表操作
class Meta:
model = models.Student
fields = ["name","teaname",]
5.模糊查询
查询链接:http://example.com/api/users?search=russell
from rest_framework import filters
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [filters.SearchFilter]
search_fields = ['username', 'email']
二、结合django_filters查询
参考链接:https://django-filter.readthedocs.io/en/stable/ref/filters.html
1.通用查询
在app下新建filter.py文件,写入如下内容:
import django_filters
from commodity.models import TaskMission, Task
class TaskMissionFilter(django_filters.FilterSet):
create_time_lte = django_filters.DateTimeFilter(field_name="create_time", lookup_expr='gte')
create_time_gte = django_filters.DateTimeFilter(field_name="create_time", lookup_expr='lte')
rank = django_filters.CharFilter('rank', lookup_expr='contains') # 对'notes'字段进行操作,不填默认为desc
class Meta:
model = TaskMission
fields = ['create_time_lte', 'create_time_gte', 'create_time', 'demandid', 'satelliteplatform',
'tasknumber', 'type', 'status', 'time', 'rank']
# fields = {'price': ['lt', 'gt']}
2.views.py中引用
@method_decorator(csrf_exempt, name="dispatch")
class TaskMissionView(MyModelViewSet):
"""
list:
不带路径参数获取全部
create:
新增一条记录
注:因测控调用本接口接口不传状态对应时间,在新增记录时需要测控给的查询接口获取状态时间!!!
"""
queryset = TaskMission.objects.all().order_by('-id')
serializer_class = TaskMissionSerializer
# 认证
authentication_classes = [JWTAuthentication]
# 权限
permission_classes = []
# 分页器
pagination_class = MallPageNumberPagination
# 搜索和排序
filter_backends = [DjangoFilterBackend, OrderingFilter]
filterset_class = TaskMissionFilter
ordering_fields = ['create_time']
ordering = ['-create_time'] # 默认排序
3.自定义方法
class TaskFilter(django_filters.FilterSet):
exclude_mission_state = django_filters.CharFilter(method='exclude_state', label='排除状态')
def exclude_state(self, queryset, field, value):
print('value', value)
return queryset.exclude(missiondata__mission_state__in=value)
4.__in查询
class TaskFilter(django_filters.FilterSet):
mission_state__in = django_filters.BaseInFilter(field_name="missiondata__mission_state")
class Meta:
model = Task
fields = ['mission_state__in ']
## url:http://wwwxxx.com/tasks/?mission_state__in=100,101,103
三、排序
查询链接:http://example.com/api/users?ordering=username ;
http://example.com/api/users?ordering=-username ;
http://example.com/api/users?ordering=account,username
from rest_framework.filters import OrderingFilter, SearchFilter
class UserListView(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
filter_backends = [OrderingFilter]
ordering_fields = ['username', 'email']
ordering = ['username'] #默认排序