JSONParser和JSONRenderer之间的区别

the*_*rit 8 django serialization json django-rest-framework

我正在浏览关于序列化的django rest框架教程,其中我遇到了JSONRenderersJSONParsers .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)
Run Code Online (Sandbox Code Playgroud)

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

还有JSONRenderer和JSONParser如何工作?

Mat*_*tko 12

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

例如.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()
Run Code Online (Sandbox Code Playgroud)

这是什么发生在这里.

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

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

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

instance = serializer.save()
Run Code Online (Sandbox Code Playgroud)

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

如您所见,viewset中没有 Form数据,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,)
Run Code Online (Sandbox Code Playgroud)