DRF框架基本使用
1. 总纲
web开发的两种模式(前后端不分离&前后端分离)
-> RestAPI设计风格
-> 使用Django基础知识自定义一套RestAPI接口
-> 分析定义RestAPI接口开发时的主要工作
-> DRF框架的特点及使用。
2. web开发的两种方式
开发方式 说明
前后端不分离 前端看到的页面效果是由后端进行控制的,后端进行模板渲染,返回渲染之后完整页面。
前后端分离 后端只返回前端所需要的数据,至于数据在前端怎么展示,由前端自己控制。
3. Restful API设计风格
GET /books/: 返回所有图书的信息
GET /books/1/: 返回指定的图书的信息
POST /books/: 返回创建的图书信息
PUT /books/1/: 返回修改的图书信息
DELETE /books/1/: 空文档
RestfulAPI 风格关键点:
1)设计url地址时,地址尽量使用名词,不要使用动词。
2)执行不同的操作,要采用不同的请求方式。
GET 获取
POST 新建
PUT 修改
DELETE 删除
3)过滤参数放在查询字符串中。
4)响应状态码的选择
200 获取或修改
201 新建
204 删除
400 客户端请求有误
404 请求的资源找不到
500 服务器错误
5)响应数据返回json.
需求:
序列化: 在上面例子中,把模型对象转换为python字典或json数据过程,就叫做序列化过程。
反序列化: 在上面例子中,把字典数据和json数据转换保存到模型对象中过程,就叫做反序列化过程。
1)定义序列化器类
from rest_framework import serializers
#serializers.Serializer: DRF框架中所有序列化器类父类
serializers.ModelSerializer: Serializer类的子类,在Serializer基础上增加一些功能
class User(object):
“”“用户类”""
def init(self, username, age):
self.username = username
self.age = age
class UserSerializer(serializers.Serializer):
“”“用户序列化器类”""
# 序化器字段名 = serializers.字段类型(选项参数)
username = serializers.CharField()
age = serializers.IntegerField()
if name == ‘main’:
# 创建user对象
user = User(‘smart’, 18)
{
'username': 'smart',
'age': 18
}
# 创建一个序列化器类对象
serializer = UserSerializer(user)
# 获取序列化之后数据
print(serializer.data)
1. 序列化器-序列化功能
1)序列化单个对象
获取对象
book = BookInfo.objects.get(id=1)
创建序列化器对象
serializer = BookInfoSerializer(book)
#获取序列化之后的数据
serializer.data
2)序列化多个对象
获取所有的图书
books = BookInfo.objects.all()
创建序列化器对象
serializer = BookInfoSerializer(books, many=True)
获取序列化之后的数据
serializer.data
3)关联对象的嵌套序列化
将关联对象序列化为关联对象的主键 PrimaryKeyRelatedField
hbook = serializers.PrimaryKeyRelatedField(label=‘图书’, read_only=True)
使用指定的序列化器将关联对象进行序列化
hbook = BookInfoSerializer(label=‘图书’)
将关联对象序列化为关联对象模型类__str__方法返回值 StringRelatedField
hbook = serializers.StringRelatedField(label=‘图书’)
注意: 如果关联的对象有多个,在定义字段的时候,需要添加many=True
2. 序列化器-反序列化功能
1)反序列化-数据校验
data = {‘btitle’: ‘python’, ‘bpub_date’: ‘1991-1-1’}
#创建序列化器对象
serializer = BookInfoSerializer(data=data)
#调用is_valid
进行数据校验
serilaizer.is_valid() # 校验通过返回True,否则返回False
获取校验失败的错误信息
serializer.errors
#获取校验之后的数据
serializer.validated_data
补充序列化器验证
#1. 自定义验证方法,给序列化器对应的字段增加选项参数validators
#2. 直接在序列化器类中定义验证方法针对特定的字段进行验证,方法名称: validate_
#3. 在序列化器类中定义validate方法进行验证:结合多个字段的内容进行验证
2)反序列化-数据保存
数据保存之后必须通过校验。
数据新增:
data = {‘btitle’: ‘python’, ‘bpub_date’: ‘1991-1-1’}
#创建序列化器对象
serializer = BookInfoSerializer(data=data)
调用is_valid
进行数据校验
serilaizer.is_valid() # 校验通过返回True,否则返回False
#数据保存,调用序列化器类中create,可以实现create方法实现数据新增
serializer.save()
数据更新:
book = BookInfo.objects.get(id=9)
data = {‘btitle’: ‘python-2’, ‘bpub_date’: ‘1991-1-1’}
创建序列化器对象
serializer = BookInfoSerializer(book,data=data)
调用is_valid
进行数据校验
serilaizer.is_valid() # 校验通过返回True,否则返回False
数据保存,调用序列化器类中update,可以实现update方法实现数据更新
serializer.save()
3. ModelSerializer
1)基于模型类的字段自动生成序列化器类的字段。
2)实现create和update方法。
request对象: 不再是Django原始的HttpRequest对象,而是由DRF框架封装成了Request类的对象。
request.data: 包含解析之后的请求体的数据,并且已经转换成字典或类字典(QueryDict, OrderedDict) 相当于Django原始request对象中(request.POST, request.FILES, request.body) request.query_params: 包含查询字符串的数据,相当于Django原始request对象中request.GET
Response对象:
直接返回Respone对象,传入原始的响应数据,会根据客户端的请求头Accpet把响应数据转换为对应的格式进行返回,默认返回json,仅支持json或html
异常处理: 将某些异常自动处理,给客户端返回对应的错误信息
其他功能:
1)认证
2)权限
3)限流
继承自APIView,在APIView功能的基础上,封装操作序列化器和操作数据库的方法,经常配合Mixin扩展进行使用。
序列化器操作:
属性: serializer_class -> 指定视图所使用序列化器类
方法:
get_serializer_class: 返回当前视图所使用的序列化类
get_serializer: 创建一个序列化器类的对象
数据库操作:
属性: query set -> 指定视图所使用的查询集
方法:
get_queryset: 返回当前视图所使用的查询集
get_object: 从查询集中查询一个对象(默认根据主键pk进行查询)
其他功能:
1)分页
2)过滤
DRF框架
类名 说明
APIView 1)继承自View,封装了Django 本身的HttpRequest对象为Request对象。2)统一的异常处理。 3)认证&权限&限流。
GenericAPIView 1)继承自APIView,提供了操作序列化器和数据库数据的方法,通常和Mixin扩展类配合使用。2)过滤&分页。
DRF提供了5个扩展类,封装了5个通用的操作流程。
类名 说明
ListModelMixin 提供了一个list方法,封装了返回模型数据列表信息的通用流程。
CreateModelMixin 提供了一个create方法,封装了创建一个模型对象数据信息的通用流程。
RetrieveModelMixin 提供了一个retrieve方法,封装了获取一个模型对象数据信息的通用流程。
UpdateModelMixin 提供了一个update方法,封装了更新一个模型对象数据信息的通用流程。
DestroyModelMixin 提供了一个destroy方法,封装了删除一个模型对象数据信息的通用流程。
2. 子类视图
为了方便我们开发RestAPI,DRF框架除了提供APIView和GenericAPIView视图类之外,还提供了一些子类视图类,这些子类视图类同时继承了GenericAPIView和对应的Mixin扩展类,并且提供了对应的请求方法。
类名 说明
ListAPIView 1)继承自ListModelMixin和GenericAPIView。2)如果想定义一个视图只提供列出模型列表信息的接口,继承此视图类是最快的方式。
CreateAPIView 1)继承自CreateModelMixin和GenericAPIView。2)如果想定义一个视图只提供创建一个模型信息的接口,继承此视图类是最快的方式。
RetrieveAPIView 1)继承自RetrieveModelMixin和GenericAPIView。2)如果想定义一个视图只提供获取一个模型信息的接口,继承此视图类是最快的方式。
UpdateAPIView 1)继承自UpdateModelMixin和GenericAPIView。2)如果只想定义一个视图只提供更新一个模型信息的接口,继承此视图类是最快的方式。
DestroyAPIView 1)继承自DestroyModelMixin和GenericAPIView。2)如果只想定义一个视图只提供删除一个模型信息的接口,继承此视图类是最快的方式。
ListCreateAPIView 1)继承自ListModelMixin,CreateModelMixin和GenericAPIView。2)如果只想定义一个视图提供列出模型列表和创建一个模型信息的接口,继承此视图类是最快的方式。
RetrieveUpdateAPIView 1)继承自RetrieveModelMixin,UpdateModelMixin和GenericAPIView。2)如果只想定义一个视图提供获取一个模型信息和更新一个模型信息的接口,继承此视图类是最快的方式。
RetrieveDestroyAPIView 1)继承自RetrieveModelMixin,DestroyModelMixin和GenericAPIView。2)如果只想定义一个视图提供获取一个模型信息和删除一个模型信息的接口,继承此视图类是最快的方式。
RetrieveUpdateDestoryAPIView 1)继承自RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin和GenericAPIView。2)如果只想定义一个视图提供获取一个模型信息和更新一个模型信息和删除一个模型信息的接口,继承此视图类是最快的方式。
示例1:
1. 获取一组图书数据 GET /books/
class BookListView(ListAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
1. 获取指定的图书数据 GET /books/(?P\d+)/
class BookDetailView(RetrieveAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
1. 获取指定的图书数据 GET /books/(?P\d+)/
2. 更新指定的图书数据 PUT /books/(?P\d+)/
class BookDetailView(RetrieveUpdateAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
将操作同一组资源的处理方法放在同一个类中(视图集),处理方法不要以请求方式命名,而是以对应的action命名,
list: 提供一组数据
create: 创建一条新数据
retrieve: 获取指定的数据
update: 更新指定的数据
destroy: 删除指定的数据
进行url配置时需要指明请求方法和处理函数之间的对应关系。
类名 说明
ViewSet 1)继承自ViewSetMixin和APIView。2)如果使用视图集时不涉及数据库和序列化器的操作,可以直接继承此类。
GenericViewSet 1)继承自ViewSetMixin和GenericAPIView。2)如果使用视图集涉及数据库和序列化器的操作,可以直接继承此类。
ModelViewSet 1)继承自5个Mixin扩展类和GenericViewSet。2)如果使用视图集想一次提供通用的5种操作,继承这个类是最快的。
ReadOnlyModelViewSet 1)继承自ListModelMixin,RetrieveModelMixin和GenericViewSet。2)如果使用视图集想一次提供list操作和retrieve操作,继承这个类是最快的。
示例1:
1. 获取一组图书信息(list) GET /books/
2. 新建一本图书信息(create) POST /books/
class BookInfoViewSet(ListModelMixin,
CreateModelMixin,
GenericViewSet)
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
1. 获取一组图书信息(list) GET /books/
2. 获取指定图书信息(retrieve) GET /books/(?P\d+)/
class BookInfoViewSet(ReadOnlyModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
1. 获取一组图书信息(list) GET /books/
2. 获取指定图书信息(retrieve) GET /books/(?P\d+)/
3. 更新指定图书信息(update) PUT /books/(?P\d+)/
class BookInfoViewSet(UpdateModelMixin,
ReadOnlyModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
注: 除了常见的5种基本操作之外,如果想给一个视图集中添加其他处理方法,直接在视图集中定义即可。
1)路由Router是专门配合视图集来使用的,可以使用Router自动生成视图集中相应处理函数对应的URL配置项。
2)使用Router自动生成视图集中相应处理函数对应的URL配置项时,除了常见的5种基本操作之外,如果视图集中有添加的其他处理方法,则需要给这些方法加上action装饰器之后,才会动态生成其对应的URL配置项。
其他功能
认证&权限