DjangoRESTframework (DRF )框架⼊门之序列化【⼀】
1. Web 应⽤模式
在开发Web 应⽤中,有两种应⽤模式:
前后端不分离
前后端分离
2. api 接⼝
为了在团队内部形成共识、防⽌个⼈习惯差异引起的混乱,我们需要到⼀种⼤家都觉得很好的接⼝实现规范,⽽且这种规范能够让后端写的接⼝,⽤途⼀⽬了然,减少双⽅之间的合作成本。⽬前市⾯上⼤部分公司开发⼈员使⽤的接⼝服务架构主要有:restful 、rpc 。rpc: 翻译成中⽂:远程过程调⽤[远程服务调⽤].post 请求
action=get_all_student¶ms=301&sex=1
接⼝多了,对应函数名和参数就多了,前端在请求api 接⼝时,就会⽐较难.容易出现重复的接⼝restful: 翻译成中⽂: 资源状态转换.把后端所有的数据/⽂件都看成资源.
那么接⼝请求数据,本质上来说就是对资源的操作了.
web 项⽬中操作资源,⽆⾮就是增删查改.所以要求在地址栏中声明要操作的资源是什么,然后通过http 请求动词来说明对资源进⾏哪⼀种操作.
3. RESTful API
规范
REST 全称是Representational State Transfer ,中⽂意思是表述(编者注:通常译为表征)性状态转移。 它⾸次出现在2000年Roy Fielding 的博⼠论⽂中。RESTful 是⼀种定义Web API 接⼝的设计风格,尤其适⽤于前后端分离的应⽤模式中。
这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接⼝,所以在定义接⼝时,客户端访问的URL 路径就表⽰这种要操作的数据资源。⽽对于数据资源分别使⽤POST 、DELETE 、GET 、UPDATE 等请求动作来表达对数据的增删查改。
事实上,我们可以使⽤任何⼀个框架都可以实现符合restful 规范的API 接⼝。
4. 序列化
api 接⼝开发,最核⼼最常见的⼀个过程就是序列化,所谓序列化就是把数据转换格式,序列化可以分两个阶段:序列化: 把我们识别的数据转换成指定的格式提供给别⼈。
例如:我们在django 中获取到的数据默认是模型对象,但是模型对象数据⽆法直接提供给前端或别的平台使⽤,所以我们需要把数据进⾏序列化,变成字符串或者json 数据,提供给别⼈。反序列化:把别⼈提供的数据转换/还原成我们需要的格式。
例如:前端js 提供过来的json 数据,对于python ⽽⾔就是字符串,我们需要进⾏反序列化换成模型类对象,这样我们才能把数据保存到数据库中。
5. Django Rest_Framework
核⼼思想: 缩减编写api 接⼝的代 -- DRF
Django REST framework 是⼀个建⽴在Django 基础之上的Web 应⽤开发框架,可以快速的开发REST API 接⼝应⽤。在REST framework 中,提供了序列化器Serialzier 的定义,可以帮助我们简化序列化与反序列化的过程,不仅如此,还提供丰富的类视图、扩展类、视图集来简化视图的编写⼯作。REST framework 还提供了认证、权限、限流、过滤、分页、接⼝⽂档等功能⽀持。REST framework 提供了⼀个API 的Web
可视化界⾯来⽅便查看测试接⼝。
特点
提供了定义序列化器Serializer 的⽅法,可以快速根据 Django ORM 或者其它库⾃动序列化/反序列化;提供了丰富的类视图、Mixin 扩展类,简化视图的编写;
丰富的定制层级:函数视图、类视图、视图集合到⾃动⽣成 API ,满⾜各种需要;多种⾝份认证和权限认证⽅式的⽀持;[jwt]内置了限流系统;
直观的 API web 界⾯;可扩展性,插件丰富
6. 环境安装与配置
DRF 需要以下依赖:
Python (2.7, 3.2, 3.3, 3.4, 3.5, 3.6)Django (1.10, 1.11, 2.0)
DRF 是以Django 扩展应⽤的⽅式提供的,所以我们可以直接利⽤已有的Django 环境⽽⽆需从新创建。(若没有Django 环境,需要先创建环境安装Django )
6.1 安装DRF
前提是已经安装了django ,建议安装在虚拟环境# mkvirtualenv drfdemo -p python3# pip install django
pip install djangorestframework
6.1.1 创建django 项⽬
cd ~/Desktop
django-admin startproject drfdemo
使⽤pycharm 打开项⽬,设置虚拟环境的解析器,并修改manage.py 中的后缀参数。
6.2 添加rest_framework 应⽤
请求⽅法请求地址后端操作GET /students 获取所有学⽣POST /students 增加学⽣
GET /students/获取编号为pk 的学⽣PUT /students/修改编号为pk 的学⽣DELETE
/students/
删除编号为pk 的学⽣
在settings.py的INSTALLED_APPS中添加'rest_framework'。
INSTALLED_APPS = [
...
'rest_framework',
]
接下来就可以使⽤DRF提供的功能进⾏api接⼝开发了。在项⽬中如果使⽤rest_framework框架实现API接⼝,主要有以下三个步骤:
将请求的数据(如JSON格式)转换为模型类对象
操作数据库
将模型类对象转换为响应的数据(如JSON格式)
接下来,我们快速体验下四天后我们学习完成drf以后的开发代码。接下来代码不需要理解,看步骤。
6.3 体验drf完全简写代码的过程
6.3.1. 创建模型操作类
class Student(models.Model):
# 模型字段
name = models.CharField(max_length=100,verbose_name="姓名",help_text='提⽰⽂本:不能为空')
sex = models.BooleanField(default=1,verbose_name="性别")
age = models.IntegerField(verbose_name="年龄")
class_null = models.CharField(max_length=5,verbose_name="班级编号")
description = models.TextField(max_length=1000,verbose_name="个性签名")
class Meta:
db_table="tb_student"
verbose_name = "学⽣"
verbose_name_plural = verbose_name
为了⽅便测试,所以我们可以先创建⼀个数据库。
create database students charset=utf8;
6.3.1.1 执⾏数据迁移
把students⼦应⽤添加到INSTALL_APPS中
初始化数据库连接
安装pymysql
pip install pymysql
主引⽤中__init__.py设置使⽤pymysql作为数据库驱动
import pymysql
pymysql.install_as_MySQLdb()
settings.py配置⽂件中设置mysql的账号密码
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
# },
'default': {
'ENGINE': 'django.sql',
'NAME': "students",
"HOST": "127.0.0.1",
"PORT": 3306,
"USER": "root",
"PASSWORD":"123",
}
}
终端下,执⾏数据迁移。
python manage.py makemigrations
python manage.py migrate
错误列表
# 执⾏数据迁移 python manage.py makemigrations 报错如下:
解决⽅案:
注释掉 python/site-packages/django/backends/mysql/base.py中的35和36⾏代码。
# 执⾏数据迁移发⽣以下错误:
解决⽅法:
backends/mysql/operations.py146⾏⾥⾯新增⼀个⾏代码:
6.3.2. 创建序列化器
例如,在django项⽬中创建学⽣⼦应⽤。
python manage.py startapp students
在students应⽤⽬录中新建serializers.py⽤于保存该应⽤的序列化器。
创建⼀个StudentModelSerializer⽤于序列化与反序列化。
# 创建序列化器类,回头会在试图中被调⽤
class StudentModelSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = "__all__"
model 指明该序列化器处理的数据字段从模型类Student参考⽣成
fields 指明该序列化器包含模型类中的哪些字段,'all'指明包含所有字段
6.3.3. 编写视图
在students应⽤的views.py中创建视图StudentViewSet,这是⼀个视图集合。
from rest_framework.viewsets import ModelViewSet
from .models import Student
from .serializers import StudentModelSerializer
# Create your views here.
class StudentViewSet(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
queryset 指明该视图集在查询数据时使⽤的查询集
serializer_class 指明该视图在进⾏序列化或反序列化时使⽤的序列化器
6.3.4. 定义路由
在students应⽤的urls.py中定义路由信息。
from . import views
from uters import DefaultRouter
# 路由列表
urlpatterns = []
router = DefaultRouter() # 可以处理视图的路由器,⾃动通过视图来⽣成增删改查的url路径
最后把students⼦应⽤中的路由⽂件加载到总路由⽂件中.
ib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path("stu/",include("students.urls")),
]
6.3.5. 运⾏测试
运⾏当前程序(与运⾏Django⼀样)
python manage.py runserver
在浏览器中输⼊⽹址127.0.0.1:8000,可以看到DRF提供的API Web浏览页⾯:
1)点击链接127.0.0.1:8000/stu/students 可以访问获取所有数据的接⼝,呈现如下页⾯:
2)在页⾯底下表单部分填写学⽣信息,可以访问添加新学⽣的接⼝,保存学⽣信息:
点击POST后,返回如下页⾯信息:
3)在浏览器中输⼊⽹址127.0.0.1:8000/stu/students/5/,可以访问获取单⼀学⽣信息的接⼝(id为5的学⽣),呈现如下页⾯:
4)在页⾯底部表单中填写学⽣信息,可以访问修改学⽣的接⼝:
点击PUT,返回如下页⾯信息:
5)点击DELETE按钮,可以访问删除学⽣的接⼝:
返回,如下页⾯:
7. 序列化器-Serializer
作⽤:
1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串
2. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
3. 反序列化,完成数据校验功能
7.1 定义序列化器
Django REST framework中的Serializer使⽤类来定义,须继承⾃rest_framework.serializers.Serializer。
接下来,为了⽅便演⽰序列化器的使⽤,我们先创建⼀个新的⼦应⽤sers
python manage.py startapp sers
我们已有了⼀个数据库模型类students/Student
from django.db import models
# Create your models here.
class Student(models.Model):
# 模型字段
name = models.CharField(max_length=100,verbose_name="姓名",help_text="提⽰⽂本:账号不能为空!")
sex = models.BooleanField(default=True,verbose_name="性别")
age = models.IntegerField(verbose_name="年龄")
class_null = models.CharField(max_length=5,verbose_name="班级编号")
description = models.TextField(verbose_name="个性签名")
class Meta:
db_table="tb_student"
verbose_name = "学⽣"
verbose_name_plural = verbose_name
我们想为这个模型类提供⼀个序列化器,可以定义如下:
from rest_framework import serializers
# 声明序列化器,所有的序列化器都要直接或者间接继承于 Serializer
# 其中,ModelSerializer是Serializer的⼦类,ModelSerializer在Serializer的基础上进⾏了代码简化
class StudentSerializer(serializers.Serializer):
"""学⽣信息序列化器"""
# 1. 需要进⾏数据转换的字段
id = serializers.IntegerField()
name = serializers.CharField()
age = serializers.IntegerField()
sex = serializers.BooleanField()
description = serializers.CharField()
# 2. 如果序列化器集成的是ModelSerializer,则需要声明调⽤的模型信息
# 3. 验证提交的数据的代码
# 4. 编写添加和更新模型的代码
注意:serializer不是只能为数据库模型类定义,也可以为⾮数据库模型类的数据定义。serializer是独⽴于数据库之外的存在。常⽤字段类型:
选项参数:
通⽤参数:
7.2 创建Serializer 对象
定义好Serializer 类后,就可以创建Serializer 对象了。Serializer 的构造⽅法为:
Serializer(instance=None, data=empty, **kwarg)说明:
1)⽤于序列化时,将模型类对象传⼊instance 参数2)⽤于反序列化时,将要被反序列化的数据传⼊data 参数
3)除了instance 和data 参数外,在构造Serializer 对象时,还可通过context 参数额外添加数据,如s
erializer = AccountSerializer(account, context={'request': request})通过context 参数附加的数据,可以通过Serializer 对象的context 属性获取。
使⽤序列化器的时候⼀定要注意,序列化器声明了以后,不会⾃动执⾏,需要我们在视图中进⾏调⽤才可以。序列化器⽆法直接接收数据,需要我们在视图中创建序列化器对象时把使⽤的数据传递过来。序列化器的字段声明类似于我们前⾯使⽤过的表单系统。开发restful api 时,序列化器会帮我们把模型数据转换成字典.
drf 提供的视图会帮我们把字典转换成json,或者把客户端发送过来的数据转换字典.
字段
字段构造⽅式BooleanField BooleanField()NullBooleanField NullBooleanField()
CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=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') format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如
"5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'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: ⼩数点位置DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)DurationField DurationField()
ChoiceField ChoiceField(choices) choices 与Django 的⽤法相同MultipleChoiceField MultipleChoiceF
ield(choices)
FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)ListField ListField(child=, min_length=None, max_length=None)DictField
DictField(child=)
参数名称作⽤max_length 最⼤长度**min_length 最⼩长度allow_blank 是否允许为空trim_whitespace 是否截断空⽩字符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 页⾯时,显⽰的字段帮助提⽰信息
7.3 序列化器的使⽤
序列化器的使⽤分两个阶段:
在客户端请求时,使⽤序列化器可以完成对数据的反序列化。
在服务器响应时,使⽤序列化器可以完成对数据的序列化。
7.3.1 序列化
7.3.1.1 基本使⽤
1)先查询出⼀个学⽣对象
dels import Student
student = (id=3)
2)构造序列化器对象
from .serializers import StudentSerializer
serializer = StudentSerializer(instance=student) -- {}
3)获取序列化数据
通过data属性可以获取序列化后的数据
serializer.data
# {'id': 4, 'name': '⼩张', 'age': 18, 'sex': True, 'description': '猴赛雷'}
完整视图代码:
from django.views import View
django admin 自定义页面
dels import Student
from .serializers import StudentSerializer
from sponse import JsonResponse
class StudentView(View):
"""使⽤序列化器序列化转换单个模型数据"""
def get(self,request,pk):
# 获取数据
student = (pk=pk)
# 数据转换[序列化过程]
serializer = StudentSerializer(instance=student)
print(serializer.data)
# 响应数据
return JsonResponse(serializer.data)
4)如果要被序列化的是包含多条数据的查询集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,json_dumps_params={'ensure_ascii':False})
# 访问结果:
# [OrderedDict([('id', 1), ('name', 'xiaoming'), ('age', 20), ('sex', True), ('description', '测试')]), OrderedDict([('id', 2), ('name', 'xiaohui'), ('age', 22), ('sex', True), ('description', '后⾯来的测试')]), OrderedDict([('id', 4), ('name', '⼩张'), ('age', 18), ('sex', True), ('description', 在ser应⽤中创建Urls.py
from django.urls import path
from . import views
urlpatterns = [
path(r'students/',views.StudentView.as_view()),
]
别忘了在总路由中include⼀下
ib import admin
from django.urls import path,include,re_path
urlpatterns = [
path('admin/', admin.site.urls),
path('stu/',include('students.urls')),
path('ser/',include('sers.urls')),
]
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论