• 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、效果

      











  • 相关阅读:
    linux内核源码之基础准备篇
    GDB 自动化操作的技术-PYTHON
    GDB 调试PYTHON
    GCC onlinedocs
    深入CSS,让网页开发少点“坑”
    多款控件新版发布,新特性抢鲜知
    如何选择前端框架:ANGULAR VS EMBER VS REACT
    推荐10个很棒的AngularJS学习指南
    Top 15 不起眼却有大作用的 .NET功能集
    最全数据结构详述: List VS IEnumerable VS IQueryable VS ICollection VS IDictionary
  • 原文地址:https://www.cnblogs.com/venicid/p/12009444.html
Copyright © 2020-2023  润新知