def perform_create(self, serializer)结合源码解读
阅读DRF文档时,发现一段代码略费脑子,解读:
文档内容位置:https://q1mi.github.io/Django-REST-framework-documentation/tutorial/6-viewsets-and-routers_zh/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | from rest_framework.decorators import detail_route class SnippetViewSet(viewsets.ModelViewSet): """ 此视图自动提供`list`,`create`,`retrieve`,`update`和`destroy`操作。 另外我们还提供了一个额外的`highlight`操作。 """ queryset = Snippet.objects. all () serializer_class = SnippetSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly,) @detail_route (renderer_classes = [renderers.StaticHTMLRenderer]) def highlight( self , request, * args, * * kwargs): snippet = self .get_object() return Response(snippet.highlighted) def perform_create( self , serializer): serializer.save(owner = self .request.user) |
主要是试图理解最后serializer.save中传递参数owner=self.request.user时是如何将参数最终存入到数据库的.
最后一段的具体流程:
ModelViewSet调用perform_create方法--serializer调用serializer自身的save方法
serializer.save时必然是已经调用了serializer.isvalid方法,此时应该已经serializer.validated_data才是需要存储的数据,接下来就是到了perform_create的调用,也即serializer.save(owner=self.request.user),调用的就是根据源码 rest_framework/serializers.py中的序列化器类 class BaseSerializer(Field)中函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | 源码:rest_framework / serializers.py 中 class BaseSerializer(Field)<br><br> def save( self , * * kwargs): assert hasattr ( self , '_errors' ), ( 'You must call `.is_valid()` before calling `.save()`.' ) assert not self .errors, ( 'You cannot call `.save()` on a serializer with invalid data.' ) # Guard against incorrect use of `serializer.save(commit=False)` assert 'commit' not in kwargs, ( "'commit' is not a valid keyword argument to the 'save()' method. " "If you need to access data before committing to the database then " "inspect 'serializer.validated_data' instead. " "You can also pass additional keyword arguments to 'save()' if you " "need to set extra attributes on the saved model instance. " "For example: 'serializer.save(owner=request.user)'.'" ) assert not hasattr ( self , '_data' ), ( "You cannot call `.save()` after accessing `serializer.data`." "If you need to access data before committing to the database then " "inspect 'serializer.validated_data' instead. " ) validated_data = { * * self .validated_data, * * kwargs} if self .instance is not None : self .instance = self .update( self .instance, validated_data) assert self .instance is not None , ( '`update()` did not return an object instance.' ) else : self .instance = self .create(validated_data) assert self .instance is not None , ( '`create()` did not return an object instance.' ) return self .instancek |
源码中出现一段代码将validated_data进行重新赋值,加入kwargs中的参数到validated_data中:
这段代码就是在视图中,以及反序列化校验之后,保存之前额外加入数据的关键所在.
实现了后期灵活添加不需要校验字段的可能性.
截取自w3cschool中文DRF教程:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通