JSONParser和JSONRenderer之间的区别

14

我正在学习 Django Rest Framework 的序列化教程,但遇到了 JSONRenderersJSONParsers 部分的困难。以下是其中提到的代码:

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是如何工作的呢?


2
序列化是将对象转换为字符串(在您的情况下为JSON),而反序列化是相反的过程。您具体在问什么? - Selcuk
是的,同样的事情,但更详细地解释一下。我知道书本上的定义,但对此并没有很好的理解。 - the_unknown_spirit
1个回答

19

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

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

让我们来看看https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py中的默认create方法。该方法从通过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()创建序列化程序的新实例(您之前设置了序列化程序类),它将请求数据作为参数。请求数据是(这很重要)字典。字典是Python通用数据结构

serializer.is_valid()方法检查请求数据是否有效。如果是,则可以访问序列化程序数据,也是一个字典

serializer.save()方法创建并将模型实例(代码段)实际持久化到数据库中。 您可以像这样直接访问实例。

instance = serializer.save()

然后你返回一个填充了序列化器数据的响应对象给客户端。

正如你所看到的,在视图集中没有表单数据、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格式返回序列化器数据给客户端,而不是字典。这就是 JSONRenderer 的作用。它将字典转换为JSON,并在响应类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,)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接