• 01_Tutorial 1: Serialization 序列化


    1、序列化

    1、官方教程

    https://q1mi.github.io/Django-REST-framework-documentation/tutorial/1-serialization_zh/

    https://www.django-rest-framework.org/tutorial/1-serialization/

    2、序列化方式1:serializers.Serializer

    # 序列化方式1:serializers.Serializer
    # 序列化方式1:serializers.Serializer
    
    class SnippetSerializer1(serializers.Serializer):
        """序列化,正反"""
        """
        序列化字段  GET请求
        """
        id = serializers.IntegerField(read_only=True)
        title = serializers.CharField(required=False, allow_blank=True, max_length=100)
    
        code = serializers.CharField(style={'base_template': 'textarea.html'})
        # 多文本框的类型,比如XML,HTML,SHELL, python
        # 在某些情况下如何显示,比如渲染HTML的时候
        # {'base_template': 'textarea.html'}标志等同于在Django Form类中使用widget=widgets.Textarea
    
        linenos = serializers.BooleanField(required=True)
        language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
        style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')
    
        """
        反序列化字段  POST,PUT请求
        """
    
        def create(self, validated_data):
            """
            根据提供的验证过的数据,创建并返回一个新的snippet实例
            """
            return Snippet.objects.create(**validated_data)  # 保存到数据库
    
        def update(self, instance, validated_data):
            """
            根据提供的验证过的数据更新和返回一个已经存在的`Snippet`实例。
            """
            instance.title = validated_data.get('title', instance.title)  # 如果post该字段则取该字段,否则直接从instance中取
            instance.code = validated_data.get('code', instance.code)
            instance.linenos = validated_data.get('linenos', instance.linenos)
            instance.language = validated_data.get('language', instance.language)
            instance.style = validated_data.get('style', instance.style)
            instance.save()  # 保存到db
            return instance

    3、view视图

    from django.test import TestCase
    
    # Create your tests here.
    
    
    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    from rest_framework.renderers import JSONRenderer
    from rest_framework.parsers import JSONParser
    
    
    # ## 序列化  GET方法
    def test1():
        snippet = Snippet(code='foo = "bar"
    ')
        snippet.save()
    
        snippet = Snippet(code='print "hello world"
    ')  # 获取字段,其他的都default
        snippet.save()  # 保存到db
        serializer = SnippetSerializer(snippet)  # 序列化为一个class对象
        serializer.data
        # {'id': 2, 'title': '', 'code': 'print "hello world"
    ', 'linenos': False, 'language': 'python', 'style': 'friendly'}
        type(serializer.data)  # 现在是什么类型呢?  ReturnDict
        # <class 'rest_framework.utils.serializer_helpers.ReturnDict'>
    
        content = JSONRenderer().render(serializer.data)  # 转化为json, Python原生数据类型
        # content
        # b'{"id":2,"title":"","code":"print \"hello world\"\n","linenos":false,"language":"python","style":"friendly"}'
        type(content)
        # <class 'bytes'>
    
    
    # ## 反序列化 POST PUT
    def test2(content):
        from django.utils.six import BytesIO  # IO,内存的数据
    
        stream = BytesIO(content)  # 获取内存中的数据    # <_io.BytesIO object at 0x00000264CC1FE780>
        data = JSONParser().parse(stream)  # 解析为data,什么类型?  一个流(stream)解析为Python原生数据类型
        type(data)  # <class 'dict'>
    
        serializer = SnippetSerializer(data=data)  # 序列化
        serializer.is_valid()  # 校验
        # True
        serializer.validated_data  # 校验通过的数据
        # OrderedDict([('title', ''), ('code', 'print "hello world"'),('linenos', False), ('language', 'python'), ('style', 'friendly')])
        type(serializer.validated_data)
        # <class 'collections.OrderedDict'>
    
        serializer.save()  # 保存到db,什么类型?   将Python原生数据类型恢复成正常的对象实例
        # <Snippet: Snippet object (3)>

    总结

    # ## 总结
    '''
    POST方法create   
    反序列化      Python原生数据类型 --->  模型实例
    
    1、json类型的数据,每个字段必须存在    
    b'{"id":2,"title":"","code":"print \"hello world\"\n","linenos":false,"language":"python","style":"friendly"}'
    
    2、解析成为dict字典,<class 'dict'>                             Python原生数据类型
    data = JSONParser().parse(stream)
    
    3、序列化,<class 'snippets.serializers.SnippetSerializer'>
    serializer = SnippetSerializer(data=data)
    
    4、是否校验通过
    serializer.is_valid()
    
    5、校验后的数据, <class 'collections.OrderedDict'>
    serializer.validated_data
    
    6、保存到DB,<Snippet: Snippet object (3)>                       正常的对象实例
    serializer.save()
    
    '''
    
    
    '''
    GET list方法总结  
    序列化   模型实例 --->   Python原生数据类型
    
    1、接收每个字段,snippet = Snippet(code='foo = "bar"
    ')
    code='foo = "bar"
    ', title='', style='friendly',language='python', linenos=False
    
    2、保存到DB   <class 'snippets.models.Snippet'>
    snippet.save()
    
    3、序列化,对象                                                    模型实例
    serializer = SnippetSerializer(snippet)         
    
    4、序列化的数据    # <class 'rest_framework.utils.serializer_helpers.ReturnDict'>
    serializer.data
    
    5、转换为json数据   <class 'bytes'>                               Python原生数据类型
    content = JSONRenderer().render(serializer.data)  
    
    '''

    4、序列化方式2:推荐,serializers.ModelSerializers

    # 序列化方式2:serializers.ModelSerializers  (推荐)
    """
    1、快捷方式
    2、自动,确定一组字段
    3、默认实现简单的create与update方法

    # 序列化方式2:serializers.ModelSerializers  (推荐)
    """
    1、快捷方式
    2、自动,确定一组字段
    3、默认实现简单的create与update方法
    """
    class SnippetSerializer(serializers.ModelSerializer):
        class Meta:
            model = Snippet
            fields = ['id', 'title', 'code', 'linenos', 'language', 'style']

    查看所有字段

    # 通过打印,序列化器类实例的结构(representation),查看它的所有字段。
    from snippets.serializers import SnippetSerializer
    serializer = SnippetSerializer()
    print(serializer)
    print(repr(serializer))   # repr 规范string形式
    # SnippetSerializer():
    #    id = IntegerField(label='ID', read_only=True)
    #    title = CharField(allow_blank=True, max_length=100, required=False)
    #    code = CharField(style={'base_template': 'textarea.html'})
    #    linenos = BooleanField(required=False)
    #    language = ChoiceField(choices=[('Clipper', 'FoxPro'), ('Cucumber', 'Gherkin'), ('RobotFramework', 'RobotFramework'), ('abap', 'ABAP'), ('ada', 'Ada')...
    #    style = ChoiceField(choices=[('autumn', 'autumn'), ('borland', 'borland'), ('bw', 'bw'), ('colorful', 'colorful')...

    5、视图

    from django.shortcuts import render
    
    # Create your views here.
    
    from django.http import HttpResponse
    from django.views.decorators.csrf import csrf_exempt
    from rest_framework.renderers import JSONRenderer   # 渲染器
    from rest_framework.parsers import JSONParser       # 解析器
    
    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    
    
    class JSONResponse(HttpResponse):
        """
         一个把content数据,渲染为json数据的HTTPResponse
              An HttpResponse that renders its content into JSON.
        """
        def __init__(self, data, **kwargs):
            content = JSONRenderer().render(data)
            kwargs['content_type'] = 'applications/json'
            super(JSONResponse, self).__init__(content, **kwargs)
            # def __init__(self, content_type=None, status=None, reason=None, charset=None):
    
    
    # 列出所有现有的snippet或创建一个新的snippet  /snippet
    @csrf_exempt  # 从不具有CSRF令牌的客户端对此视图进行POST
    def snippet_list(request):
        """
        列出所有的code snippet,或创建1个新的snippet
        """
        if request.method == 'GET':
            snippet = Snippet.objects.all()                         # queryset对象实例
            serializer = SnippetSerializer(snippet, many=True)      # serializer模型实例
            return JSONResponse(serializer.data)                    # 序列化的数据 ReturnDict ---> json
    
        elif request.method == 'POST':
            data = JSONParser().parse(request)                      # python原生数据 --->  json
            serializer = SnippetSerializer(data=data)               # serializer模型实例
            if serializer.is_valid():                               # data验证
                serializer.save()                                   # 保存到db, 正常的对象实例
                return JSONResponse(serializer.data, status=201)    # 验证通过的data,ReturnDict ---> json
            return JSONResponse(serializer.errors, status=400)      # 未验证的通过的data,
    
    
    # 一个与单个snippet对象相应的视图 snippet/1
    @csrf_exempt
    def snippet_detail(request, pk):
        """
        获取,更新,删除1个code snippet
        """
        try:
            snippet = Snippet.objects.get(pk=pk)
        except Snippet.DoesNotExist:
            return HttpResponse(status=404)
    
        if request.method == 'GET':
            serializer = SnippetSerializer(snippet)
            return JSONResponse(serializer.data)
    
        elif request.method == 'POST':
            data = JSONParser().parse(request)
            serializer = SnippetSerializer(snippet, data=data)
            if serializer.is_valid():
                serializer.save()
                return JSONResponse(serializer.data)
            return JSONResponse(serializer.errors, status=400)
    
        elif request.method == 'DELETE':
            snippet.delete()
            return HttpResponse(status=404)

    6、效果

      











  • 相关阅读:
    解析大型.NET ERP系统 权限模块设计与实现
    Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架
    解析大型.NET ERP系统 单据编码功能实现
    解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
    Windows 10 部署Enterprise Solution 5.5
    解析大型.NET ERP系统 设计异常处理模块
    解析大型.NET ERP系统 业务逻辑设计与实现
    解析大型.NET ERP系统 多国语言实现
    Enterprise Solution 管理软件开发框架流程实战
    解析大型.NET ERP系统 数据审计功能
  • 原文地址:https://www.cnblogs.com/venicid/p/12009444.html
Copyright © 2020-2023  润新知