JSONParser和JSONRenderer之间的区别

时间:2016-02-27 11:48:29

标签: json django serialization django-rest-framework

我在序列化方面经历了django rest framework tutorial,其中我遇到了 JSONRenderers JSONParsers .Below是那里提到的代码:

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from django.utils.six import BytesIO

snippet = Snippet(code='foo = "bar"\n')
snippet.save()

snippet = Snippet(code='print "hello, world"\n')
snippet.save()
serializer = SnippetSerializer(snippet)
serializer.data
# {'pk': 2, 'title': u'', 'code': u'print "hello, world"\n', 'linenos': False, 'language': u'python', 'style': u'friendly'}
content = JSONRenderer().render(serializer.data)
content
# '{"pk": 2, "title": "", "code": "print \\"hello, world\\"\\n", "linenos": false, "language": "python", "style": "friendly"}'

stream = BytesIO(content)
data = JSONParser().parse(stream)

我知道JSONParser用于反序列化数据,而JSONRenderer用于序列化,但我仍然不能理解数据序列化和反序列化之间的区别。有人可以让我清楚地了解这一点。(非常感谢你回答一个例子。)

还有JSONRenderer和JSONParser如何工作?

1 个答案:

答案 0 :(得分:9)

我将从 viewsets 开始。视图和视图集是DRF中的类,其中大多数应用程序逻辑都会发生。

EG。 ModelViewSet是负责响应POST,PUT,PATCH,GET,DELETE HTTP方法的CRUD操作的类。

让我们看一下来自https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py的默认创建方法这个方法创建模型的实例,从数据(如果它们有效)通过HTTP POST方法发送并将它们保存到数据库。

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()

这是发生在这里的事情。

self.get_serializer()创建序列化程序的新实例(之前设置序列化程序类),它将request.data作为参数。 request.data是(这是重要的)字典。 Dictionary是通用python数据结构

serializer.is_valid()方法检查request.data是否有效。如果是,您可以访问serializer.data - 也是字典

serializer.save()方法创建并将模型的实际实例(Snippet)保存到数据库。 您可以直接访问此类实例

instance = serializer.save()

然后将使用serializer.data填充的Response对象返回给客户端。

如您所见,viewset中有表单数据,JSON,XML,HTML等。您使用python数据类型,序列化程序负责将字典“翻译”到您特定模型的实例并向后。 但是客户端以JSON的形式在HTTP请求中发送数据(在您的情况下)。

JSONParser 负责将JSON转换为字典。解析在请求类https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/request.py中实现,请注意这不是标准的django HttpRequest模型。

您可以设置多个解析器,然后请求将根据HTTP请求标头选择正确的解析器:Content-type。

第二件事是,你必须以JSON的形式将serializer.data返回给客户端,而不是字典。那是 JSONRenderer 的作用。它将dict转换为JSON,并在Response类https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/response.py中实现。您还可以设置多个渲染器,然后根据接受的媒体类型http标头选择正确的渲染器。

完整视图集定义的示例可能是:

from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser


class SnippetViewSet(viewsets.ModelViewSet):

    queryset = Snippet.objects.all()
    serializer_class = SnippetSerializer
    renderer_classes = (JSONRenderer, )
    parser_classes = (JSONParser,)