Django-RESTful Api 之序列化

前后端分离

  • 前台和后台的开发分离开发,就需要借助 API。API 就是开发人员提供的编程接口以供他人调用

安装

1
pip install djangorestframework

构建开发环境

什么是序列化?

  • 把模型对象转换为 JSON 格式然后响应出去,这样便于客户端调用时解析

创建序列化类

  • 在应用目录下创建名为 serializers.py 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # -*- coding:utf-8 -*-
    from rest_framework import serializers
    from myApp.models import Student


    # 只能序列化Student模型对象
    class StudentSerializer(serializers.ModelSerializer):
    class Meta:
    model = Student
    fields = ("id", "name", "sex", "age", "content", "grade")

使用序列化类

  • 进入 shell 模式

    1
    python manage.py shell
  • 增加学生

    1
    2
    3
    4
    >>> from myApp.models import Student, Grade
    >>> grade = Grade.objects.get(pk=1)
    >>> stu = Student.create("liudehua",True,50,"liudehua shuai",grade)
    >>> stu.save()
  • 引入序列化类,创建序列化对象查看可序列化的字段

    1
    2
    3
    >>> from myApp.serializers import StudentSerializer
    >>> serializer = StudentSerializer()
    >>> print(serializer)
  • 依据学生创建序列化对象,再对对象进行序列化操作

    1
    2
    3
    4
    5
    >>>serializer = StudentSerializer(stu)
    >>> print(serializer.data)
    {'id': 1, 'name': 'liudehua', 'sex': True, 'age': 50, 'contend': 'liudehua shuai', 'grade': 1}
    >>> print(type(serializer.data))
    <class 'rest_framework.utils.serializer_helpers.ReturnDict'>
  • 将数据渲染成 json 格式

    1
    2
    3
    4
    >>> from rest_framework.renderers import  JSONRenderer
    >>> content = JSONRenderer().render(serializer.data)
    >>> print(content)
    b'{"id":1,"name":"liudehua","sex":true,"age":50,"contend":"liudehua shuai","grade":1}'
  • 反序列化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> from rest_framework.renderers import  JSONRenderer
    >>> content = JSONRenderer().render(serializer.data)
    >>> print(content)
    b'{"id":1,"name":"liudehua","sex":true,"age":50,"contend":"liudehua shuai","grade":1}'
    >>> from rest_framework.parsers import JSONParser
    >>> from django.utils.six import BytesIO
    >>> stream = BytesIO(content)
    >>> print(stream)
    <_io.BytesIO object at 0x00000181C2588728>
    >>> stu2=JSONParser().parse(stream)
    >>> print(stu2)
    {'id': 1, 'name': 'liudehua', 'sex': True, 'age': 50, 'contend': 'liudehua shuai', 'grade': 1}

    当客户需要修改、增加、删除数据时,就要把过程反过来,就叫做反序列化。

  • 检测数据并保存

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> stu2.save()
    Traceback (most recent call last):
    File "<console>", line 1, in <module>
    AttributeError: 'dict' object has no attribute 'save'
    >>> serializer = StudentSerializer(data=stu2)
    >>> print(serializer.is_valid())
    True
    >>> print(serializer.validated_data)
    OrderedDict([('name', 'liudehua'), ('sex', True), ('age', 50), ('contend', 'liudehua shuai'), ('grade', <Grade: python01>)])
    >>> serializer.save()
    <Student: liudehua>

视图实现使用序列化

1
2
url(r'^students/$', views.studentsList),
url(r'^students/(?P<pk>\d+)', views.studentDetail),
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
from django.shortcuts import render
from django.http import HttpResponse, JsonResponse
from myApp.models import Student, Grade
from myApp.serializers import StudentSerializer
from rest_framework.parsers import JSONParser
from rest_framework.renderers import JSONRenderer
from django.utils.six import BytesIO


# Create your views here.
def studentsList(request):
if request.method == "GET":
stus = Student.objects.all()
serializer = StudentSerializer(stus, many=True)
return JsonResponse(serializer.data, safe=False)
elif request.method == "POST":
content = JSONRenderer().render(request.POST)
stream = BytesIO(content)
data = JSONParser().parse(stream)
serializer = StudentSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)


def studentDetail(request, pk):
try:
stu = Student.objects.get(pk=pk)
except Student.DoesNotExist as e:
return HttpResponse(status=404)
if request.method == "GET":
serializer = StudentSerializer(stu)
return JsonResponse(serializer.data)
elif request.method == "PUT":
content = JSONRenderer().render(request.POST)
stream = BytesIO(content)
data = JSONParser().parse(stream)
serializer = StudentSerializer(stu, data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, status=201)
return JsonResponse(serializer.errors, status=400)
elif request.method == "DELETE":
stu.delete()
return HttpResponse(status=204)