美文网首页Django来敲门
Django-REST:002-API接口序列化

Django-REST:002-API接口序列化

作者: 大牧莫邪 | 来源:发表于2018-07-04 10:01 被阅读144次

    RESTful风格下,比较充分的利用了HTTP1.1标准中规定的集中请求方式

    l GET:用于提交向服务器获取数据的请求

    l POST:用于提交数据给服务器进行数据更新的请求

    l PUT:用于提交数据给服务器进行数据添加的请求

    l DELETE:用于提交给服务器删除条件数据的请求

    在这样的处理风格下,目前更加适合项目开发并且成本较低的一种比较流行的开发模式:项目的前后端分离结构模型的优势更加突出,通过RESTful风格指定的格式定义不同的数据处理的请求方式,后端只需要提供对应的接口,前端视图部分负责调用进行数据展示;数据的交互全部交给异步调用进行实现,能最大程度的发挥项目开发过程中开发人员的能力!

    下面是一个基本案例[参考官方文档整理],了解一下RESTful在Django项目中的主要工作流程和操作方式

    1. 创建案例项目

    执行命令创建项目

    
    django-admin startproject myrest_ex02
    
    

    进入项目根目录中,执行命令创建一个应用:用于进行代码文件描述的应用

    
    django-admin startapp snippet
    
    

    2. 配置开发环境

    确保在django的基础上,安装restful需要的各种依赖包

    
    pip install django
    
    pip install djangorestframework # restful框架
    
    pip install pygments # 代码文件描述模块
    
    

    打开项目配置文件settings.py,添加rest框架模块和我们的应用程序模块

    
    INSTALLED_APPS = [
     …… **'rest_framework'**, **'snippet.apps.SnippetConfig'**,
    ]
    
    

    3. 数据模型定义

    打开snippet应用的数据模型定义模块models.py,添加一个定义代码描述的类型

    
    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())
    
    
    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 snippet
    
    python manage.py migrate
    
    

    4. 数据模型序列化处理

    在snippet应用中,添加一个序列化模块,用于进行数据模型对象的序列化操作

    在myrest_ex02/snippet/目录下创建文件:serializers.py

    # coding:utf-8
    
    from rest_framework import serializers
    from .models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
    
    
    class SnippetSerializer(serializers.ModelSerializer):
        class Meta:
            model = Snippet
            fields = ['id', 'title', 'code', 'linenos', 'language', 'style']
    
    
    

    PS:序列化操作本身提供了一个基本接口serializers.Serializer类型,但是这个类型本身提供的实现机制不利于代码的复用性,封装的ModelSerializer更加友好的提供了序列化的实现方式更加友好!

    5. 交互测试

    已经开发好了一部分序列交互的部分,我们接下来就可以通过django shell交互方式进行数据对象的序列化操作测试了,测试通过之后继续开发视图部分代码。

    执行命令进入shell交互窗口

    python manage.py shell

    (1) 在交互窗口中导入我们需要的模块

    
    from snippet.models import Snippet
    
    from snippet.serializers import SnippetSerializer
    
    from rest_framework.renderers import JSONRenderer
    
    from rest_framework.parsers import JSONPerser
    
    

    (2) 添加数据到数据库

    
    >>> snippet = Snippet(code='name = "jerry"')
    
    >>> snippet.save()
    
    >>>
    
    >>> snippet2 = Snippet(code='print("hello python")')
    
    >>> snippet.save()
    
    

    (3) 序列化对象数据

    
    >>> serializer = SnippetSerializer(snippet2)
    
    >>> serializer.data
    
    {'id': None, 'title': '', 'code': 'print("hello python")', 'linenos': False, 'language': 'python', 'sty
    
    le': 'friendly'}
    
    >>> **serializer2 = SnippetSerializer(snippet)**
    
    >>> **serializer2.data**
    
    {'id': 3, 'title': '', 'code': 'name = "jerry"', 'linenos': False, 'language': 'python', 'style': 'frie
    
    ndly'}
    
    

    (4) JSON格式化序列数据

    通过JSON格式化渲染的数据,就是最终可以交互的JSON字符串数据

    
    >>> content = JSONRenderer().render(serializer.data)
    
    >>>
    
    >>> content
    
    b'{"id":null,"title":"","code":"print(\\"hello python\\")","linenos":false,"language":"python","style":
    
    "friendly"}'
    
    

    (5) 反序列化JSON数据

    反序列化在WEB应用中,主要用于解析视图客户端提交的JSON数据,转化成数据对象之后进行CRUD的操作

    
    >>> from django.utils.six import BytesIO
    
    >>>
    
    >>> stream = BytesIO(content)
    
    >>> data = JSONParser().parse(stream)
    
    >>>
    
    >>> serializer = SnippetSerializer(data=data)
    
    >>> serializer.is_valid()
    
    True
    
    >>>
    
    >>> serializer.save()
    
    <Snippet: Snippet object (4)>
    
    

    (6) 序列化查询结果集

    在实际项目操作过程中,我们在Django项目里面操作的往往都是QuerySet查询结果集

    对于查询结果集的序列化处理方式如下

    
    >>> res = SnippetSerializer(Snippet.objects.all(), many=True)
    
    >>> res.data
    
    [OrderedDict([('id', 1), ('title', ''), ('code', 'foo="bar"\n'), ('linenos', False), ('language', 'pyth
    
    on'), ('style', 'friendly')]), OrderedDict([('id', 2), ('title', ''), ('code', 'print("hello world")\n'
    
    ), ('linenos', False), ('language', 'python'), ('style', 'friendly')]), OrderedDict([('id', 3), ('title
    
    ', ''), ('code', 'name = "jerry"'), ('linenos', False), ('language', 'python'), ('style', 'friendly')])
    
    , OrderedDict([('id', 4), ('title', ''), ('code', 'print("hello python")'), ('linenos', False), ('langu
    
    age', 'python'), ('style', 'friendly')])]
    
    

    6. 视图函数:API数据接口

    经过第5步的交互测试,已经完成了对数据的处理方式的基本操作测试

    接下来开始开发视图交互函数,也就是给其他调用的客户端提供数据的API接口函数!

    (1) 数据列表接口函数——snippet_list

    打开项目应用的视图处理模块:snippet.views

    开发数据列表接口函数

    
    from django.http import HttpResponse, JsonResponse
    
    from django.views.decorators.csrf import csrf_exempt
    
    from rest_framework.renderers import JSONRenderer
    
    from rest_framework.parsers import JSONParser
    
    from .models import Snippet
    
    from .serializers import SnippetSerializer
    
    @csrf_exempt
    
    def snippet_list(reuqest):
    
        if request.method == “GET”:
    
             # 查询所有数据
    
             snippets = Snippet.objects.all()
    
             # 序列化数据
    
             serializers = SnippetSerializer(snippets, many=True)
    
             # 返回数据
             return JsonResponse(serializers.data, safe=False)
    
        elif request.method == “POST”:
    
            # 解析提交的数据
    
              data = JSONParser().parse(request)
    
            # 反解析序列数据
    
              serializers = SnippetSerializer(data=data)
    
           # 验证并保存数据
    
              if serializers.is_valid():
    
                      serializers.save()
    
                    # 返回视图页面
    
                      return JsonResponse(serializer.data, status=201)
    
                return JsonResponse(serializer.errors, status=400)
    
    

    (2) 对象数据增删改API接口函数开发

    定义一个接口函数,通过request.method直接判断进行不同请求方式的处理

    
    @csrf_exempt
    
    def snippet_detail(request, pk):
    
    # 首先查询得到数据对象
    
    try:
    
      snippet = Snippet.objects.get(pk=pk)
    
    except Snippet.DoesNotExist:
    
      return HttpResponse(status=404)
    
    # 获取单个数据的操作
    
    if request.method == “GET”:
    
    # 序列化数据
    
      serializers = SnippetSerializer(snippet)
    
      return JsonResponse(serializers.data)
    
    # 提交数据的操作
    
    elif request.method == “PUT”:
    
    # 反解析数据
    
      data = JSONParser().parse(request)
    
    # 序列化操作
    
      serializers = SnippetSerializer(data=data)
    
    # 验证有效性并存储
    
      if serializers.is_valid():
    
      serializers.save()
    
    # 返回视图处理界面
    
      return JsonResponse(serializers.data)
    
      return JsonResponse(serializers.errors, status=400)
    
    # 删除数据的操作
    
    elif request.method ==”DELETE”:
    
      snippet.delete()
    
      return HttpResponse(status=204)
    
    

    7. 运行测试

    (1) 浏览器测试

    执行命令运行项目

    
    python manage.py shell
    
    

    浏览器访问http://localhost:8000/snippet/ 查看所有数据列表

    image.png

    浏览器访问http://localhost:8000/snippet/1/查看指定的对象数据

    |

    image.png

    |

    其他请求方式通过工具进行测试验证

    (2) Postman测试工具

    l get测试

    |

    image.png

    |

    l delete测试

    |

    image.png

    |

    再次查询

    |

    image.png

    |

    相关文章

      网友评论

      本文标题:Django-REST:002-API接口序列化

      本文链接:https://www.haomeiwen.com/subject/wvosuftx.html