Django REST Framework

WEB 应用模式

前后端不分离
depended_frontend_backend.png
  • 前端页面效果由后端控制(后端渲染页面或重定向) 前端的静态文件(css,js)和后端的django框架都部署在一个服务器上
  • 此模式适合纯网页应用,当后端对接APP时,后端返回的网页接口不再适用于前端APP应用
前后端分离
indepent_frontend_backend.png
  • 后端只返回前端所需要的数据,不再渲染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接口

  • 接口设计
  1. 请求方式(GET/POST/PUT/DELETE)
  2. 请求路径
  3. 请求参数(路径参数/字符串参数/表单/json)
  4. 返回结果
  • 开发REST API时,视图中做的三件事:
  1. 将请求的数据(如JSON格式)转换成模型类对象,将前端发送的数据反序列化为模型类对象,并保存到数据库中
  2. 操作数据库
  3. 将模型类对象转化成响应的数据(如JSON格式),将数据库数据序列化为前端所需要的格式,并返回
  • 序列化 将程序中的数据结构类型转换成其他格式(字典,JSON,XML等)
  • 反序列化 将其他格式(字典,JSON,XML等)转换成程序中的数据

DRF

Django REST framework可以简化以下两部分的代码编写,提高REST API的开发速度

  • 在序列化与反序列化时,虽然操作的数据不同,但执行的过程却是相似的,这部分代码是可以复用简化编写的
  • 在开发REST API的视图中,每个视图具体操作的数据不同,但增、删、改、查的实现流程基本套路化,这部分代码也是可以复用简化编写的:
  1. 增:校验请求数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
  2. 删:判断要删除的数据是否存在 -> 执行数据库删除
  3. 改:判断要修改的数据是否存在 -> 校验请求的数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
  4. 查:查询数据库 -> 将数据序列化并返回

DRF工程搭建

  1. 安装DRF
pip install djangorestframework
  1. 在settings.py的INSTALLED_APPS中添加rest_framework

序列化器

  • 序列化器的作用
    • 进行数据的校验
    • 对数据对象进行转换
  • serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义

定义序列化器Serializer

  1. 新建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()
  1. 创建的序列化器中的字段参考模型类中的字段
  • 字段中的常用参数
常用参数 参数说明
read_only 该字段仅用于序列化输出,默认False
write_only 该字段仅用于反序列化输入,默认False
required 该字段在反序列化时必须输入,默认True
default 反序列化时使用的默认值
  1. 在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方法的返回值)
关联对象的序列化器 关联对象的序列化器
  1. 主表嵌套副表
#一对多,关联多个对象数据,使用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)
  1. 副表嵌套主表
#多对一,关联单个对象数据
hbook = serializers.PrimaryKeyRelatedField(read_only=True)
hbook = serializers.StringRelatedField(read_only=True)
hbook = BookHeroSerialzer()

反序列化使用

反序列化:对前端请求来的参数进行验证,保存或更新,需要在序列化类中指明哪些字段进行反序列化验证

  1. 验证
#视图中
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
  1. 保存/更新
#视图中,反序列化保存更新,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}}

你可能感兴趣的:(Django REST Framework)