• django rest_framework入门二-序列化


    在前一节中,我们已经粗略地介绍了rest_framework的作用之一序列化,下面我们将详细探究序列化的使用。

    1.新建一个app snippets

    python manage.py startapp snippets
    

    更新配置文件tutorial/settings.py,注册到APPS

    INSTALLED_APPS = (
        ...
        'rest_framework',
        'snippets.apps.SnippetsConfig',
    )
    

    2.创建Model,定义实体
    编辑snippets/models.py,添加Snippet模型,该模型用来存储代码片段

    from django.db import models
    from pygments.lexers import get_all_lexers
    from pygments.styles import get_all_styles
    
    LEXERS = [item for item in get_all_lexers() if item[1]]
    LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
    STYLE_CHOICES = sorted((item, item) for item in get_all_styles())
    
    
    # Create your models here.
    class Snippet(models.Model):
        created = models.DateTimeField(auto_now_add=True)
        title = models.CharField(max_length=100, blank=True, default='')
        code = models.TextField()
        linenos = models.BooleanField(default=False)
        language = models.CharField(choices=LANGUAGE_CHOICES, default='python', max_length=100)
        style = models.CharField(choices=STYLE_CHOICES, default='friendly', max_length=100)
    
        class Meta:
            ordering = ('created',)
    

    在数据库中建表

    python manage.py makemigrations
    python manage.py migrate
    

    3.创建Serializer类,提供序列化,反序列化方法
    新建serializers.py,代码如下:

    from rest_framework import serializers
    from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
    
    
    class SnippetSerializer(serializers.Serializer):
        pk = serializers.IntegerField(read_only=True)
        title = serializers.CharField(required=False, allow_blank=True, max_length=100)
        code = serializers.CharField(style={'base_template': 'textarea.html'})
        linenos = serializers.BooleanField(required=False)
        language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
        style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')
        created = serializers.DateTimeField(read_only=True)
    

    SnippetSerializer定义了序列化/反序列化的字段,包括字段的类型,范围,不符合的字段值将无法完成序列化/反序列化
    Serializer类,有一个save()方法,用来将json格式数据,新增或修改对象。原理如下:

    class SnippetSerializer(serializers.Serializer):
        pk = serializers.IntegerField(read_only=True)
        title = serializers.CharField(required=False, allow_blank=True, max_length=100)
        code = serializers.CharField(style={'base_template': 'textarea.html'})
        linenos = serializers.BooleanField(required=False)
        language = serializers.ChoiceField(choices=LANGUAGE_CHOICES, default='python')
        style = serializers.ChoiceField(choices=STYLE_CHOICES, default='friendly')
        created = serializers.DateTimeField(read_only=True)
    
        def create(self, validated_data):
            return Snippet.objects.create(**validated_data)
    
        def update(self, instance, validated_data):
            instance.title = validated_data.get('title', instance.title)
            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()
            return instance
    

    4.Serializer类的使用
    新增Snippet对象

    from snippets.models import Snippet
    
    
    snippet = Snippet(code='print "hello, world"
    ')
    snippet.save()
    

    使用Serializer类序列化Snippet对象

    # Create your tests here.
    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    
    
    snippet = Snippet.objects.first()
    
    serializer = SnippetSerializer(snippet)
    print(type(serializer.data))
    print(serializer.data)
    

    运行结果:

    返回json格式数据

    使用Serializer类反序列化Snippet对象

    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    
    
    data = {
        'code': 'print "hello, python"
    '
    }
    serializer = SnippetSerializer(data=data)
    if serializer.is_valid():
        snippet = serializer.save()
        print(snippet)
    else:
        print(serializer.error_messages)
    

    运行结果:

    返回Snippet对象

    5.ModelSerializer代替Serializer
    Serializer和Model有太多重复的地方,因此有了ModelSerializer,代码示例如下:

    from rest_framework import serializers
    from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
    
    
    class SnippetSerializer(serializers.ModelSerializer):
        class Meta:
            model = Snippet
            fields = ("id", "title", "code", "linenos", "language", "style", "created")
    

    运行结果:

    ModelSerializer没有使用任何黑科技,实质和Serializer类一样,也是根据Model创建Serializer的过程

    6.使用serializer类编写视图
    编辑views.py,代码示例如下:

    import json
    
    from django.shortcuts import render
    from django.http import HttpResponse
    from django.views.decorators.csrf import csrf_exempt
    
    from snippets.models import Snippet
    from snippets.serializers import SnippetSerializer
    
    
    # Create your views here.
    @csrf_exempt
    def snippet_list(request):
        if request.method == 'GET':
            snippets = Snippet.objects.all()
            serializer = SnippetSerializer(snippets, many=True) #返回字典列表
            result_type = type(serializer.data)
            result = json.dumps(serializer.data) # 字典转化为json字符串
            return HttpResponse(result)
    
        if request.method == 'POST':
            data = request.body
            data = json.loads(data) # json字符串转字典
            serializer = SnippetSerializer(data=data)
            if serializer.is_valid():
                serializer.save()
                result = serializer.data
            else:
                result = {
                    'status': "failed"
                }
            result = json.dumps(result) # 字典转化为json字符串
            return HttpResponse(result)
    

    csrf_exempt:允许跨域访问
    snippet_list: GET--访问Snippet列表
    POST--新增Snippet实体

    编辑tutorial/urls.py,加入访问snippet地址

    from snippets import views
    
    urlpatterns = [
        url(r'^snippets/$', views.snippet_list),
        url(r'^admin/', admin.site.urls),
        url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
    ]
    

    运行结果:
    post访问

    get访问

  • 相关阅读:
    Video视频播放中断问题排查记录
    下一站:手机安全
    数据之美 之一
    数据之美 之二
    数据之美 之三
    Groovy入门
    Java8新特性(Lambda表达式、Stream流、Optional类)等
    websocket和ajax的区别(和http的区别)
    java泛型<? extends E>和<? super E>的区别和适用场景
    JAVA反射
  • 原文地址:https://www.cnblogs.com/shijingjing07/p/9072876.html
Copyright © 2020-2023  润新知