self.get_serializer方法来自Django REST Framework中的哪个位置?

时间:2016-07-04 05:04:14

标签: python django-rest-framework

DRF source code中,有一个get_serializer方法。它不是从对象继承而来的,它不是CreateModelMixin类中的方法。这种方法来自哪里?

serializer = self.get_serializer(data=request.data)

这里是上下文的大块代码。

from __future__ import unicode_literals

from rest_framework import status
from rest_framework.response import Response
from rest_framework.settings import api_settings


class CreateModelMixin(object):
    """
    Create a model instance.
    """
    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        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': data[api_settings.URL_FIELD_NAME]}
        except (TypeError, KeyError):
            return {}

有一些SO帖子也使用这种方法。与thisthisthis一样。但我仍然无法弄清楚实施的位置。

3 个答案:

答案 0 :(得分:12)

CreateModelMixin以及所有其他mixin类(例如ListModelMixinUpdateModelMixin等)在rest_framework/mixins.py文件中定义。

这些mixin类提供模型上的所有基本CRUD操作。您只需在通用视图中定义serializer_classqueryset即可执行所有这些操作。 DRF已在单独的mixin类中分离出这些常用功能,以便它们可以在视图中注入/混合并在需要时使用。

  

在DRF源代码中,有get_serializer方法。事实并非如此   继承自object并且它不是CreateModelMixin中的方法   类。这种方法来自哪里?

GenericAPIView中,定义了get_serializer方法。不同mixin类和GenericAPIView类的组合为我们different generic views提供了不同的用例。

class GenericAPIView(views.APIView):
    """
    Base class for all other generic views.
    """

    def get_serializer(self, *args, **kwargs):
        """
        Return the serializer instance that should be used for validating and
        deserializing input, and for serializing output.
        """
        serializer_class = self.get_serializer_class()
        kwargs['context'] = self.get_serializer_context()
        return serializer_class(*args, **kwargs)

其他通用视图会继承相关mixinGenericAPIView

例如。 CreateAPIView继承CreateModelMixinGenericAPIView以提供 create-only 端点。

# rest_framework/generics.py
class CreateAPIView(mixins.CreateModelMixin,
                    GenericAPIView):
    ...

答案 1 :(得分:1)

您可以查看方法的__file____module__成员(如果有)以了解相关信息。 inspect也有getsourcefilegetsourcelines使用来自函数代码对象的数据,具体来说,<function>.f_code.co_filename.co_firstline

例如,这将检索从DictMixin继承的方法的源信息:

>>> c=ConfigParser._Chainmap()
>>> f=c.__len__
>>> dump(f.__code__)    #my custom function that dumps attributes
<...>
co_filename : /usr/lib/python2.7/UserDict.py
co_firstlineno : 179
<...>
#same with inspect
>>> inspect.getsourcefile(f)
'/usr/lib/python2.7/UserDict.py'
>>> inspect.getsourcelines(f)
(['    def __len__(self):\n', '        return len(self.keys())\n'], 179)
>>> inspect.getsource(f)
'    def __len__(self):\n        return len(self.keys())\n'
#same with __file__
>>> sys.modules[f.__module__].__file__
'/usr/lib/python2.7/UserDict.pyc'

答案 2 :(得分:1)

如果您了解类继承(尽管并不建议您不这样做),那么它会有所帮助。

CreateModelMixin将由基于类的视图使用,例如:

class YourViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):

get_serializerGenericViewSet可用的方法(尽管可能还有其他View类可用)。

因此,基本上,如果您将使用CreateModelMixin,则仅get_serializer不可用。 (您可能还是不会这样做)。仅仅是因为您从CreateModelMixin之外的另一个类继承而来,get_serializer方法在执行create方法时才可用。

我可以举一个简单的例子说明正在发生的事情。只是为了更简单地概述正在发生的事情。

免责声明:您可能要记住,我是一名初级开发人员,所以这可能不是那里最有Python风格的代码:

class MyMixin:
    def create(self):
        serializer = self.get_serializer()
        return serializer


class FakeView:
    def get_serializer(self):
        return "Sadly I am just a string, but I could've been a serializer."


class MyFakeView(MyMixin, FakeView):
    pass

view = MyFakeView()

serializer = view.create()

print(serializer)

执行此操作将显示:

Sadly I am just a string, but I could've been a serializer.

如果您要像下面那样定义MyFakeView

class MyFakeView(MyMixin):
    pass

您将收到以下错误:

AttributeError: 'MyFakeView' object has no attribute 'get_serializer'