DRF 内如何实现view 和serializer更多交互
先说下drf 工作流
post put delete patch 请求
请求接受 ----> 路由匹配 ----> 解析器解析请求 ----> 身份认证-----> 权限判断 -----> 进入view---> 自动化调用序列化器 -----> 反序列化器 校验参数,序列化参数 入库 并返回结果----->渲染器 渲染数据 ----->响应请求
get 请求
基本一样
.......
调用序列化器 ------> 校验参数 跟据参数 序列化数据
...........
# ModelViewSet 是DRF 封装的最顶层 它把业务逻辑也整个封装进去了
# 与ModelViewSet对应的是ModelSerializer 他把整个校验过程 序列化过程 全部加入进去了
class AgencySerializer(serializers.ModelSerializer):
class Meta:
model = App
fields = '__all__'
class AppViewSet(viewsets.ModelViewSet):
queryset = App.objects.all().order_by('-create_time')
serializer_class = AppSerializer
permission_classes = (IsAdminUser,)
search_fields = ('admin')
# 以下为 drf 源码 ----
# 举个例子现在客户端 想要创建一条app 相关的数据那DRF 是怎么实现的呢
#1 当路由匹配上上后 他会去找到一个create 该方法源于他的父类CreateModelMixin方法 源码如下
def create(self, request, *args, **kwargs):
# 可以看到它首先调用get_serializer方法 创建一个serializer 实例 并传入 请求的数据 该方法源于 ModelViewSet的曾祖类 GenericAPIView
serializer = self.get_serializer(data=request.data)
# 接着这个实例使用is_valid 方法 该方法 会自动把传入数据校验一遍
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
serializer.save()
def get_success_headers(self, data):
try:
return {'Location': str(data[api_settings.URL_FIELD_NAME])}
except (TypeError, KeyError):
return {}
显而易见这里会存在一个问题 就是所有入参都是基于用户请求 所有响应都是基于序列化后的结果我们想要加入更多的逻辑存在困难,也不用着急DRF也是一个成熟的框架了 这也可以给出解决方案
# view 传向serializer 中利用context上下文属性
# view 中
data = '经过一阵激烈的数据处理得到'
serializer = HistoryLoginSerializer(queryset, many=True, context={'data': data})
# serializer 中
class AppSerializer(Serializer)
# 定义一个方法
def get_user(self, instance):
# 得到之前传入的数据了 这样非客户端传入数据也可以传入了
data = self.context['data']
# serializer传向 view
# view 中
serializer.is_valid(raise_exception=True) # 校验并反序列化参数
# 保存数据 入库并返回新的对象 这个返回值得内容可以在 serializer 里面改的
data = serializer.save()
aap = data['instance']
new_data = data['new_data']
# serializer 中
#serilizer 中
# serializer.save() 最终会处理一下 并调用 create 方法所以我们可以 重写create 方法
class AppSerializer(Serializer)
''' 忽略了一些东西''''
def create(self, validated_data):
# 正常业务逻辑 得到数据
validated_data
aap = App(**validated_data ).save()
# 新加入我们需要数据
new_data ='也许这里有一阵激烈的数据处理'
return {'instance': aap, 'new_data': new_data}