1. 作用

1. 序列化,序列化器会把模型对象转成字典,经过 response 以后变成 json 字符串
2. 反序列化,把客户端发送过来的数据,经过 request 以后变成字典,序列化器可以把字典转成模型
3. 反序列化,完成数据的校验

2. 定义序列化器

Django REST framework 中的 Serializer 使用类来定义,必须继承 rest_framework.serializers.Serializer

接下来,为了方便使用序列化器需要我们自己创建一个新的子应用 app02

python manage.py startapp app02

这里我们需要重新编写一份数据库模型类 Student

from django.db import models

# Create your models here.

class Student(models.Model):
name = models.CharField(max_length=32,verbose_name='姓名')
sex = models.BooleanField(default=True,verbose_name="性别")
age = models.IntegerField(verbose_name="年龄")
description = models.TextField(verbose_name="个性签名") class Meta:
db_table = "tb_student"
verbose_name = '学生'
verbose_name_plural = verbose_name

接下来需要为这个模型类定义一个序列化器,需要如下定义(注:这里需要自己在 app02 创建一个serializer

from rest_framework import serializers

# 声明序列化器,所有的序列化器都要直接或者间接继承于 Serializer
# 其中,ModelSerializer 是 Serializer 的子类,ModelSerializer 在 Serializer 的基础上进行了代码简化
class StudentSerializer(serializers.Serializer):
"""" 学生信息序列化器 """
# 1.需要进行数据转换的字段
id = serializers.IntegerField()
name = serializers.CharField()
sex= serializers.BooleanField()
age = serializers.IntegerField()
description = serializers.CharField() # 2.如果序列化器集成的是 ModelSerializer,则需要声明调用的模型类型 # 3.验证代码 # 4.编写添加和更新模型的代码

注意:Serializer 不是只能为数据库模型类定义,也可以为非数据库类的数据定义,serializer 是独立于数据库之外的存在

常用字段类型

字段 字段构造方式
BooleanField BooleanField()
NullBooleanField NullBooleanField()
CharField CharField(max_length=None,min_length=None,allow_blank=False,trim_whitespance=True)
EmailField EmailField(max_length=None,min_length=None,allow_blank=False)
RegexField RegexField(regex,max_length=None,min_length=None,allow_blank=False)
SlugField SlugField(max_length=50,min_length=None,allow_blank=False) 
正则字段,验证正则模式[a-zA-Z0-9]+
URLField URLField(max_length=200,min_length=None,allow_blank=False)
UUIDField UUIDField(format='hex_verbose') 
1)format:'hex_verbose',如:'5ce0e9a5-5ffa-654b-cee0-1238041fb31a'
2)format:'hex',如:'5ce0e9a55ffa654bcee01238041fb31a'
3)format:'int',如:'123456789012312313134124512351145145114'
4)format:'urn',如:'urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a'
IPAddressField IPAddressField(protocol='both',unpack_ipv4=False,**options)
IntegerField IntegerField(max_value=None,min_value=None)
FloatField FloatField(max_value=None, min_value=None)
DecimalField DecimalField(
max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) 
max_digits: 最多位数 
decimal_palces: 小数点位置

选项参数

参数名称 作用
max_length 最大长度
min_length 最小长度
allow_blank 是否允为空
trim_whitespance 是否截断空白字符
max_value 最大值
min_value 最小值

通用参数

参数名称 说明
read_only 表明该字段仅用于序列化输出,默认 False
write_only 表明该字段仅用于反序列,默认 False
required 表明该字段在反序列化时必须输入,默认 True
default 反序列化时使用的默认值
allow_null 表明该字段是否允许传入 None,默认 False
validators 该字段使用的验证器
error_messages 包含错误编号与错误信息的字典
label 用于 HTML 展示 API 页面时,显示的字段名称
help_text 用于 HTML 展示 API 页面时,显示的字段帮助提示信息

3. 创建 Serializer 对象

定义好 Serializer 类,就可以创建 Serializer 对象了

Serializer 的构造方法为:

Serializer(instance=None,data=empty,**kwarg)

说明:

  1. 用于序列化时,将模型类对象传入 instance 参数
  2. 用于反序列化时,将要被反序列化的数据传入 data 参数
  3. 除了 instance 和 data 参数外,在构造 Serializer 对象时,还可通过 context 参数额外添加数据,如
serializer = AccountSerializer(account,context={"request":request})

通过 context 参数附加的数据,可以通过 Serializer 对象的 context 属性获取

  1. 使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以
  2. 序列化器无法直接接受数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来
  3. 序列化器的字段声明类似于我们前面使用过的表单系统
  4. 开发 RESTful API 时,序列化器会帮我们把模型数据转换成字典
  5. DRF 提供的视图会帮我们把字典转换为 json,或者把客户端发送过来的数据转换成字典

4. 序列化器的使用

序列化器的使用分为两个阶段:

  1. 在客户端请求时,使用序列化器可以完成对数据的反序列化
  2. 在服务端响应时,使用序列化器可以完成对数据的序列化

1) 序列化

A. 基本使用

  1. 先查询出一个学生对象
from students.models import Student

student = Student.objects.get(id=1)
  1. 构造序列化对象
from .serializers import StudentSerializer

serializer = StudentSerializer(instance=student)
  1. 获取序列化数据

通过 data 属性可以获取序列化后的数据

serializer.data
# output:{ "id": 1,"name": "小物","sex": false,"age": 18,"description": "无" }

注意这里的路由配置(主要是自己忘记了):

from django.conf.urls import url
from django.contrib import admin
from app01 import views as app01_view
from app02 import views as app02_view urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^books/', app01_view.BookView.as_view()),
url(r'^student/(?P<pk>\d+)',app02_view.StudentView.as_view())
]
  1. 如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加 many=True 参数补充说明
"""使用序列化器序列化转换多个模型数据"""
def get(self,request):
# 获取数据
student_list = Student.objects.all() # 转换数据[序列化过程]
# 如果转换多个模型对象数据,则需要加上many=True
serializer = StudentSerializer(instance=student_list,many=True)
print( serializer.data ) # 序列化器转换后的数据 # 响应数据给客户端
# 返回的json数据,如果是列表,则需要声明safe=False
return JsonResponse(serializer.data,safe=False)

B. 实际案例:实现对学生对象的增删查改

a. 查询 id=5 学生的信息

views.py

from rest_framework.views import APIView
from app02.models import Student
from app02.serializer import StudentSerializer
from rest_framework.response import Response class StudentView(APIView):
"""使用序列化器序列化转换单个模型数据"""
def get(self,request,pk):
student = Student.objects.filter(id=pk).first()
student_serializer = StudentSerializer(student)
return Response(student_serializer.data)
b. 查询所有学生的信息

view.py

class StudentsView(APIView):
""" 使用序列化器序列化转换单个模型中多个数据 """
def get(self,request):
students = Student.objects.all()
students = StudentsSerializer(students,many=True)
return Response(students.data)

urls.py

from django.conf.urls import url
from django.contrib import admin
from app02 import views as app02_view urlpatterns = [
url(r'^admin/', admin.site.urls),
# 单条数据信息查询
url(r'^student/(?P<pk>\d+)',app02_view.StudentView.as_view()),
# 多条数据信息查询
url(r'^students/',app02_view.StudentsView.as_view())
]

serializer.py

class StudentsSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField()
sex = serializers.BooleanField()
age = serializers.IntegerField()
description = serializers.CharField()
c. 新增一条数据

view.py

class StudentsView(APIView):
""" 使用序列化器序列化转换单个模型中多个数据 """ def post(self,request):
response_dict = {"status": 100, 'msg': '成功'}
student_serializer = StudentsSerializer(data=request.data)
if student_serializer.is_valid():
student_serializer.save()
response_dict['data'] = student_serializer.data
else:
response_dict['msg'] = 1001
response_dict['data'] = '数据校验失败'
response_dict['data'] = student_serializer.errors
return Response(response_dict)

serializer.py(要添加的原因是:不写 create() 方法会报错)

class StudentsSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField()
sex = serializers.BooleanField()
age = serializers.IntegerField()
description = serializers.CharField() def create(self,validated_data):
instance = Student.objects.create(**validated_data)
return instance
d. 修改一条数据

view.py

class StudentView(APIView):
""" 使用序列化器序列化转换单个模型数据 """ def put(self,request,pk):
response_dict = {"status": 100, 'msg': '成功'}
student = Student.objects.filter(id=pk).first()
student_serializer = StudentSerializer(instance=student,data=request.data)
if student_serializer.is_valid():
student_serializer.save()
response_dict['data'] = student_serializer.data
else:
response_dict['msg'] = 1001
response_dict['msg'] = '数据校验失败'
response_dict['data'] = student_serializer.errors
return Response(response_dict)

serializer.py(要添加的原因是:不写 update() 方法会报错)

class StudentSerializer(serializers.Serializer):
"""" 学生信息序列化器 """
# 1.需要进行数据转换的字段
id = serializers.IntegerField()
name = serializers.CharField()
sex= serializers.BooleanField()
age = serializers.IntegerField()
description = serializers.CharField() # 2.如果序列化器集成的是 ModelSerializer,则需要声明调用的模型类型 # 3.验证代码 # 4.编写添加和更新模型的代码
def update(self, instance, validated_data):
instance.name = validated_data.get("name")
instance.sex = validated_data.get('sex')
instance.age = validated_data.get("age")
instance.description = validated_data.get("description")
instance.save()
return instance
e. 删除一条数据

view.py

class StudentView(APIView):
""" 使用序列化器序列化转换单个模型数据 """
def delete(self,request,pk):
response_dict = {"status": 100, 'msg': '成功'}
student = Student.objects.filter(id=pk).first()
student.delete()
return Response(response_dict)
f. 完整的增删查改代码

view.py

from rest_framework.views import APIView
from app02.models import Student
from app02.serializer import StudentSerializer
from app02.serializer import StudentsSerializer
from rest_framework.response import Response class StudentView(APIView):
""" 使用序列化器序列化转换单个模型数据 """ def get(self,request,pk):
student = Student.objects.filter(id=pk).first()
student_serializer = StudentSerializer(student)
return Response(student_serializer.data) def put(self,request,pk):
response_dict = {"status": 100, 'msg': '成功'}
student = Student.objects.filter(id=pk).first()
student_serializer = StudentSerializer(instance=student,data=request.data)
if student_serializer.is_valid():
student_serializer.save()
response_dict['data'] = student_serializer.data
else:
response_dict['msg'] = 1001
response_dict['msg'] = '数据校验失败'
response_dict['data'] = student_serializer.errors
return Response(response_dict) def delete(self,request,pk):
response_dict = {"status": 100, 'msg': '成功'}
student = Student.objects.filter(id=pk).first()
student.delete()
return Response(response_dict) class StudentsView(APIView):
""" 使用序列化器序列化转换单个模型中多个数据 """
def get(self,request):
students = Student.objects.all()
students = StudentsSerializer(students,many=True)
return Response(students.data) def post(self,request):
response_dict = {"status": 100, 'msg': '成功'}
student_serializer = StudentsSerializer(data=request.data)
if student_serializer.is_valid():
student_serializer.save()
response_dict['data'] = student_serializer.data
else:
response_dict['msg'] = 1001
response_dict['data'] = '数据校验失败'
response_dict['data'] = student_serializer.errors
return Response(response_dict)

serializer.py

from rest_framework import serializers
from app02.models import Student # 声明序列化器,所有的序列化器都要直接或者间接继承于 Serializer
# 其中,ModelSerializer 是 Serializer 的子类,ModelSerializer 在 Serializer 的基础上进行了代码简化
class StudentSerializer(serializers.Serializer):
"""" 学生信息序列化器 """
# 1.需要进行数据转换的字段
id = serializers.IntegerField()
name = serializers.CharField()
sex= serializers.BooleanField()
age = serializers.IntegerField()
description = serializers.CharField() # 2.如果序列化器集成的是 ModelSerializer,则需要声明调用的模型类型 # 3.验证代码 # 4.编写添加和更新模型的代码
def update(self, instance, validated_data):
instance.name = validated_data.get("name")
instance.sex = validated_data.get('sex')
instance.age = validated_data.get("age")
instance.description = validated_data.get("description")
instance.save()
return instance class StudentsSerializer(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField()
sex = serializers.BooleanField()
age = serializers.IntegerField()
description = serializers.CharField() def create(self,validated_data):
instance = Student.objects.create(**validated_data)
return instance

urls.py

from django.conf.urls import url
from django.contrib import admin
from app02 import views as app02_view urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^student/(?P<pk>\d+)',app02_view.StudentView.as_view()),
url(r'^students/',app02_view.StudentsView.as_view())
]
 
 

前后端分离之DRF——1的更多相关文章

  1. 一.前后端分离及drf实现序列化的原理

     为什么要进行前后端分离 可pc.app.pad多端适应 SPA开发模式的流行--单页web应用(只有一html页面) 可实现前后端开发职责清(不分离时,前端是通过后端给的变量并渲染出来方式拿到数据! ...

  2. python drf+xadmin+react+dva+react-native+sentry+nginx 搭建前后端分离的博客完整平台

    前言: 经过差不多半年的开发,搭建从前端到服务器,实现了前后端分离的一个集PC端.移动端的多端应用,实属不易,今天得空,好好写篇文章,记录这些天的成果.同时也做个分享. 演示网站地址: http:// ...

  3. 前后端分离djangorestframework——认证组件

    authentication 认证是干嘛的已经不需要多说.而前后端未分离的认证基本是用cookie或者session,前后端分离的一般用token 全局认证 先创建一个django项目,项目名为drf ...

  4. 前后端分离djangorestframework——分页组件

    Pagination 为什么要分页也不用多说了,大家都懂,DRF也自带了分页组件 这次用  前后端分离djangorestframework——序列化与反序列化数据  文章里用到的数据,数据库用的my ...

  5. 前后端分离djangorestframework——路由组件

    在文章前后端分离djangorestframework——视图组件 中,见识了DRF的视图组件强大,其实里面那个url也是可以自动生成的,就是这么屌 DefaultRouter urls文件作如下调整 ...

  6. 前后端分离djangorestframework——视图组件

    CBV与FBV CBV之前说过就是在view.py里写视图类,在序列化时用过,FBV就是常用的视图函数,两者的功能都可以实现功能,但是在restful规范方面的话,CBV更方便,FBV还要用reque ...

  7. 前后端分离djangorestframework——序列化与反序列化数据

    我们写好后端的代码,要把数据交给前端的展示的,这个数据以什么类型给前端呢?学到这里,我们已经知道这个数据最好是json字符串才行,因为网络间的传输,只认字符串或者二进制,字符串就是我们的数据,二进制就 ...

  8. 前后端分离和restful开发规范

    一.web开发的两种模式 1.前后端不分离 在前后端不分离的应用模式中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,也就是后端需要控制前端的展示,前端与后端的耦合度很高. 这种应用模式比 ...

  9. Django前后端分离项目部署

    vue+drf的前后端分离部署笔记 前端部署过程 端口划分: vue+nginx的端口 是81 vue向后台发请求,首先发给的是代理服务器,这里模拟是nginx的 9000 drf后台运行在 9005 ...

随机推荐

  1. k8s二进制部署 - traefik安装

    配置traefik资源清单rbac.yaml 配置traefik资源清单 rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: name: t ...

  2. GO - LLT

    GoConvey: https://www.jianshu.com/p/e3b2b1194830 GoMonkey: https://www.jianshu.com/p/2f675d5e334e Go ...

  3. Keepalived+LVS实现LNMP网站的高可用部署

    Keepalived+LVS实现LNMP网站的高可用部署   项目需求   当我们访问某个网站的时候可以在浏览器中输入IP或者域名链接到Web Server进行访问,如果这个Web Server挂了, ...

  4. history-back

    ;!function(pkg, undefined){ //此声明函数在xback.js文件里有,在app.js里必须再声明一次,不然监听返回事件失败 var STATE = 'x-back'; va ...

  5. 编写一个c函数,该函数给出一个字节中被置为1的位的个数

    请编写一个c函数,该函数给出一个字节中被置为1的位的个数 #include <stdio.h> void fun(char ch) { int i; int temp; int count ...

  6. QUIC协议和HTTP3.0技术研究

    QUIC:基于UDP的安全可靠的HTTP/2传输协议 摘要 QUIC(Quick UDP Internet Connection)是一个新的基于UDP的管线化技术和安全传输协议. QUIC提供: 和H ...

  7. SwiftUI error All In One

    SwiftUI error All In One Instance member xxx cannot be used on type yyy Instance member 'game' canno ...

  8. git cli all in one

    git cli all in one https://www.atlassian.com/git/tutorials/learn-git-with-bitbucket-cloud git create ...

  9. H5 APP 页面移动端适配方案

    H5 APP 页面移动端适配方案 https://segmentfault.com/a/1190000011586301 https://juejin.im/post/5cbdee71f265da03 ...

  10. 「NGK每日快讯」12.3日NGK公链第30期官方快讯!