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教程:

 

posted @   EricYJChung  阅读(478)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示