我在序列化方面经历了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如何工作?
答案 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,)