1、前言
前面我们已经介绍了DjangoRestFramework的基本使用和简单的访问控制,在实践的过程中,很多同学可能也发现了一个问题就是DjangoRestFramework的响应体都是自动完成的,但是和前端同学联调的过程中,可能需要对响应体结构进行特殊封装,具体得根据业务的要求。这个是时候怎么办呢?别急,今天我们就一起来看看DjangoRestFramework的响应体该如何自定义(封装)呢?
FastApi的响应体封装点这里查看。
2、快速开始
我们知道FastApi的响应体封装是基于fastapi.responses的JSONResponse来实现的。在视图函数中直接导入调用即可。
其实DjangoRestFramework也是一样的道理,但是DjangoRestFramework的ModelViewSet自动帮我们处理了响应体,我们如果要在ModelViewSet的基础上去修改响应体,就需要创建新类继承ModelViewSet,然后对其中的CRUD方法进行重写即可。
class MyModelViewSet(ModelViewSet):
def list(self, request, *args, **kwargs):
super(MyModelViewSet, self).list(request, *args, **kwargs)
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
return Response({'code':2,'msg':'成功','data': serializer.data}) # 覆盖响应体
以上就是我们自定义的MyModelViewSet,然后我们将之前的视图函数继承的ModelViewSet替换为我们自己写的MyModelViewSet即可。
以上list方法中的代码在rest_framework.mixins中都能查看到。我们只是在开头将父类的list方法super了一下(可选),参考文档:Super()的用法。
在视图类中继承MyModelViewSet:
# Create your views here.
class PersonViewSet(MyModelViewSet):
queryset = Person.objects.all()
serializer_class = PersonModelSerializer
如上,就是这么简单,我们访问http://localhost:8989/app0/person/查看效果:
如上,我们已经成功重写了ModelViewSet的list方法,同理我们可以对create、update、destroy、retrieve方法进行统一重写。
from rest_framework.viewsets import ModelViewSet
from .models import Person
from .serializers import PersonModelSerializer
class MyModelViewSet(ModelViewSet):
# CRUD-U
def update(self, request,*args,**kwargs):
partial = kwargs.pop('partial',False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
is_valid = serializer.is_valid(raise_exception=False)
if not is_valid:
return Response({'code':5,'msg':'更新失败','data': serializer.errors})
self.perform_update(serializer)
if getattr(instance,'_prefetched_objects_cache',None):
instance._prefetched_objects_cache ={}
return Response({'code':2,'msg':'更新成功','data': serializer.data})
# CRUD-R
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
serializer = self.get_serializer(queryset, many=True)
return Response({'code':2,'msg':'成功','data': serializer.data}) # Your override
# CRUD-C
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return Response({'code':202,'msg':'创建成功','data': serializer.data})
# CRUD-D
def destroy(self, request, *args, **kwargs):
instance = self.get_object()
self.perform_destroy(instance)
return Response({'code':200,'msg':'删除成功','data': request.data})
# 单个对象详情查看
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response({'code':200,'msg':'查询成功','data': serializer.data})
以上MyModelViewSet就是我们自己封装的视图集,我们在写DjangoRestFramework的视图函数时直接继承MyModelViewSet即可实现响应体的结构统一了。
评论区