WEB 应用模式
前后端不分离
- 前端页面效果由后端控制(后端渲染页面或重定向) 前端的静态文件(css,js)和后端的django框架都部署在一个服务器上
- 此模式适合纯网页应用,当后端对接APP时,后端返回的网页接口不再适用于前端APP应用
前后端分离
- 后端只返回前端所需要的数据,不再渲染HTML页面
- 前端的静态文件和后端的django框架部署在不同的服务器上
在静态文件夹内开启静态服务器
python3 -m http.server 端口号
django框架开启后端应用服务器
实现一台物理主机,开启多个服务器功能
- 浏览器先请求部署Nginx的静态服务器,请求的内容不在Nginx中,由Nginx转发请求到部署uwisg的后端应用服务器,进行处理响应,将相应的结果返回给Nginx,再由Nginx返回给浏览器
- 前后端分离模式中,后端的每个视图都为一个接口或API, 前端通过访问接口对数据进行增删改查
RESTful设计方法
域名
- 尽量将API部署在专用域名之下
- 若API很简单,不会再扩展,可放在主域名下
版本
- API的版本号放入URL,路径参数
- 不同的版本,为同一种资源的不同表现形式,采用同一个URL,版本号在HTTP请求头信息的Accept字段中进行区分
路径
路径又称"终点"(endpoint),表示API的具体网址,每个网址代表一种资源(resource)
- 资源作为网址,只能有名词,不能有动词,而且所用的名词往往与数据库的表名对应
- API中的名词应该使用复数。无论子资源或者所有资源
HTTP动词
- GET(SELECT):从服务器取出资源(一项或多项)
- POST(CREATE):在服务器新建一个资源
- PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
- DELETE(DELETE):从服务器删除资源
过滤信息(filtering)
使用查询字符串参数对信息进行过滤
状态码(status codes)
200 OK - [GET]:服务器成功返回用户请求的数据
201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
204 NO CONTENT - [DELETE]:用户删除数据成功。
400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作
401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。
错误处理
状态码是4xx,服务器向用户返回出错信息,返回的信息中将error作为键名,出错信息作为键值。
返回结果
GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
其他
服务器返回的数据格式,应该尽量使用JSON,避免使用XML
使用django开发REST接口
- 接口设计
- 请求方式(GET/POST/PUT/DELETE)
- 请求路径
- 请求参数(路径参数/字符串参数/表单/json)
- 返回结果
- 开发REST API时,视图中做的三件事:
- 将请求的数据(如JSON格式)转换成模型类对象,将前端发送的数据反序列化为模型类对象,并保存到数据库中
- 操作数据库
- 将模型类对象转化成响应的数据(如JSON格式),将数据库数据序列化为前端所需要的格式,并返回
- 序列化 将程序中的数据结构类型转换成其他格式(字典,JSON,XML等)
- 反序列化 将其他格式(字典,JSON,XML等)转换成程序中的数据
DRF
Django REST framework可以简化以下两部分的代码编写,提高REST API的开发速度
- 在序列化与反序列化时,虽然操作的数据不同,但执行的过程却是相似的,这部分代码是可以复用简化编写的
- 在开发REST API的视图中,每个视图具体操作的数据不同,但增、删、改、查的实现流程基本套路化,这部分代码也是可以复用简化编写的:
- 增:校验请求数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
- 删:判断要删除的数据是否存在 -> 执行数据库删除
- 改:判断要修改的数据是否存在 -> 校验请求的数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
- 查:查询数据库 -> 将数据序列化并返回
DRF工程搭建
- 安装DRF
pip install djangorestframework
- 在settings.py的INSTALLED_APPS中添加rest_framework
序列化器
- 序列化器的作用
- 进行数据的校验
- 对数据对象进行转换
- serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义
定义序列化器Serializer
- 新建serializers.py,该文件用来定义序列化器类,DRF中的Serializer使用类来定义, 继承自rest_framework.serializers.Serializer
from rest_framework import serializers
from book.models import BookInfo, HeroInfo
class BookSerializers1(serializers.Serializer):
btitle = serializers.CharField()
bpub_date = serializers.DateField()
- 创建的序列化器中的字段参考模型类中的字段
- 字段中的常用参数
常用参数 | 参数说明 |
---|---|
read_only | 该字段仅用于序列化输出,默认False |
write_only | 该字段仅用于反序列化输入,默认False |
required | 该字段在反序列化时必须输入,默认True |
default | 反序列化时使用的默认值 |
- 在serializers.py中定义好类后,在视图中创建序列化器对象
Serializer(instance=None, data=empty, **kwarg)
- 序列化时,将模型类对象传入instance参数
- 反序列化时,将要被反序列化的数据传入data参数
序列化使用
在django shell 中使用序列化器
python manage.py shell
- 基本使用
- 模型类查询数据库 ,获取查询对象
- 把查询对象当作参数,进行序列化器实例化对象
- 序列化器对象通过data属性获取序列化后的数据
- 被序列化的是包含多条数据的查询集QuerySet,通过添加many=True参数补充说明
from booktest.models import BookInfo
from booktest.serializers import BookInfoSerializer
#获取单个数据
book = BookInfo.objects.get(id=2)
serializer = BookInfoSerializer(book)
serializer.data
# {'id': 2, 'btitle': '天龙八部', 'bpub_date': '1986-07-24', 'bread': 36, 'bcomment': 40, 'image': None}
#获取多条数据
book_qs = BookInfo.objects.all()
serializer = BookInfoSerializer(book_qs, many=True)
serializer.data
# [OrderedDict([('id', 2), ('btitle', '天龙八部'), ('bpub_date', '1986-07-24'), ('bread', 36), ('bcomment', 40), ('image', N]), OrderedDict([('id', 3), ('btitle', '笑傲江湖'), ('bpub_date', '1995-12-24'), ('bread', 20), ('bcomment', 80), ('image'ne)]), ]
- 关联对象嵌套序列化
关联字段方式 | 说明 |
---|---|
PrimaryKeyRelatedField | 被序列化为关联对象的主键 |
StringRelatedField | 被序列化为关联对象的字符串(str方法的返回值) |
关联对象的序列化器 | 关联对象的序列化器 |
- 主表嵌套副表
#一对多,关联多个对象数据,使用many=True参数
heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True,many=True)
heroinfo_set =serializers.StringRelatedField(read_only=True,many=True)
heroinfo_set = HeroSerialzier(many=True)
- 副表嵌套主表
#多对一,关联单个对象数据
hbook = serializers.PrimaryKeyRelatedField(read_only=True)
hbook = serializers.StringRelatedField(read_only=True)
hbook = BookHeroSerialzer()
反序列化使用
反序列化:对前端请求来的参数进行验证,保存或更新,需要在序列化类中指明哪些字段进行反序列化验证
- 验证
#视图中
ser = BookSerializer(instance,date_dict)
ser.is_valid(raise_exception=True)
ser.errors
#序列化器类中
#指定字段验证
def validate_btitle(self,value):
if value =='python':
return serializers.ValidationError("报错信息")
return value
#多个字段验证
def validate(self,attrs):
if attrs['btitle'] =='python':
return serializers.ValidationError("报错信息")
return attrs
- 保存/更新
#视图中,反序列化保存更新,save选择保存还是更新由初始化反序列器时有没有传入instance决定
ser.save()
#序列化器中
#保存使用create
def create(self,validated_date)
#更新使用update
def update(self,instance,validate_date)
模型类序列化器ModelSerializer
- ModelSerializer提供:
- 基于模型类自动生成一系列字段
- 基于模型类自动为Serializer生成validators,比如unique_together
- 包含默认的create()和update()的实现
class BookModelSerialize(serializers.ModelSerializer):
#显示指明字段
bcomment = serializers.IntegerField(max_value=200, min_value=20)
class Meta:
model = BookInfo #指定根据哪个模型类生成字段
fields = '__all__' #所有字段
# fields = ('id','btitle') #指定字段
# exclude = ('bread', ) #字段取反
read_only_fields = ('bcomment', ) #指定参与序列化的字段
extra_kwargs = {'is_delete': {'default': True}}
class HeroModelSerialize(serializers.ModelSerializer):
#显示指明字段
bcomment = serializers.IntegerField(max_value=200, min_value=20)
class Meta:
model = HeroInfo #指定根据哪个模型类生成字段
fields = '__all__' #所有字段
read_only_fields = ('hcomment', ) #指定参与序列化的字段
extra_kwargs = {'is_delete': {'default': True}}