def perform_create(self, serializer)结合源码解读

阅读DRF文档时,发现一段代码略费脑子,解读:

文档内容位置:https://q1mi.github.io/Django-REST-framework-documentation/tutorial/6-viewsets-and-routers_zh/

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)中函数:

 源码:rest_framework/serializers.py 中 class BaseSerializer(Field)

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 @ 2022-07-14 23:51  EricYJChung  阅读(529)  评论(0)    收藏  举报