DRF类 视图介绍
在DRF框架中提供了众多的通用视图基类和扩展类,用来简化视图的编写。
![](https://img-blog.csdnimg.cn/img_convert/7ebf1add5bb87765a2feb9929817862f.png)
View:Django默认的视图基类,负责将视图连接到URL,HTTP请求的基本调度。
APIView: DRF提供的所有视图基类,继承View并扩展,具备了身份认证、权限检查、 流量控制等功能。
GenericAPIView :对APIView更高层次的封装,例如增加分页、过滤器
GenericViewSet:继承GenericAPIView和ViewSet
ViewSet:继承APIView,并结合router自动映射路由
ModelViewSet:继承GenericAPIView和五个扩展类,封装好各种请求,更加完善, 业务逻辑基本不用自己写了
APIView类
DRF提供的所有视图基类,继承View并扩展,具备了身份认证、权限检查、流量控制等功能
使用APIView类
class UserView(APIView):
def get(self, request):
# print(request.query_params)
queryset = User.objects.all()
# 调用序列化器将queryset对象转为json
user_ser = UserSerializer(queryset, many=True) # 如果序列化多条数据,需要指定many=True
return Response(user_ser.data)
def post(self, request):
print(request.data)
data = {'result': 'post'}
return Response(data)
def put(self, request):
data = {'result': 'put'}
return Response(data)
def delete(self, request):
data = {'result': 'delete'}
return Response(data)
GenericAPIView类
GenericAPIView对APIView更高层次的封装,实现以下功能:
增加queryset属性,指定操作的数据,不用再将数据传给序列化器,自动实现
增加serializer_class属性,指定使用的序列化器
增加过滤器属性:filter_backends
增加分页属性:pagination_class
增加lookup_filed属性和实现get_object()方法:用于获取单条数据,可自定义默认分组名(pk)
使用GenericAPIView
class UserView(GenericAPIView):
queryset = User.objects.all() # 指定操作的数据
serializer_class = UserSerializer # 指定序列化器
lookup_field = 'id' # 指定self.get_object()默认获取id的名称
def get(self, request, id=None):
if id:
user_obj = self.get_object() # 从零方法调用指定数据(默认根据pk作为id查询条件)
user_ser = self.get_serializer(user_obj)
else:
queryset = self.get_queryset() # 从类方法调用所有数据
user_ser = self.get_serializer(queryset, many=True) # 从类方法调用序列化器
res = {'code': 200, 'msg': '成功', 'data': user_ser.data}
return Response(res)
def post(self, request):
print(request.data)
data = {'result': 'post'}
return Response(data)
def put(self, request):
data = {'result': 'put'}
return Response(data)
def delete(self, request):
data = {'result': 'delete'}
return Response(data)
ViewSet类
ViewSet视图集不再实现get()、post()等方法,而是实现以下请求方法动作
• list():获取所有数据
• retrieve():获取单个数据
• create():创建数据
• update():更新数据
• destory():删除数据
使用
class UserView(ViewSet):
lookup_field = 'id'
def retrieve(self, request, id=None):
# 获取单用户
obj = User.objects.get(id=id)
# 调用序列化器将queryset对象转为json
user_ser = UserSerializer(obj)
res = {'code': 200, 'msg': '成功', 'data': user_ser.data}
return Response(res)
def list(self, request):
# 获取所有用户
queryset = User.objects.all()
# 调用序列化器将queryset对象转为json
user_ser = UserSerializer(queryset, many=True) # 如果序列化多条数据,需要指定many=True
res = {'code': 200, 'msg': '成功', 'data': user_ser.data}
return Response(res)
def create(self, request):
# 调用序列化器将提交的数据进行反序列化
user_ser = UserSerializer(data=request.data) # request.data 用户POST
user_ser.is_valid(raise_exception=True)
user_ser.save()
res = {'code': 200, 'msg': '创建用户成功!'}
return Response(res)
def update(self, request, id=None):
data = {'result': 'put'}
return Response(data)
def destory(self, request, id=None):
obj = User.objects.get(id=id)
obj.delete()
res = {'code': 200, 'msg': '删除用户成功!'}
return Response(res
使用ViewSet类就不再需要为每一个API接口写对应的URL路由来绑定HTTP方法了,它会自动处理URL路由如下
from rest_framework import routers
from django.urls import include
# 自动生成URL路由
router = routers.DefaultRouter()
router.register(r'user', views.UserView, basename='user') # 注册视图到路由
urlpatterns += [
path('api/', include(router.urls)) # URL根路径
]
ModelViewSet 类
![](https://img-blog.csdnimg.cn/img_convert/358ea3566f1038ef69296ad773012479.png)
ModelViewSet继承GenericAPIView和五个扩展类,封装好各种请求,更加完善,业务逻 辑基本不用自己写了,只需要指定serializer_class和queryset,就可以直接进行增删改查
from rest_framework.viewsets import ModelViewSet
class UserView(ModelViewSet):
queryset = User.objects.all() # 指定操作的数据
serializer_class = UserSerializer # 指定序列化器
以上ModelViewSet虽然可以自动实现增删改查的功能,但是对于增改在一些场景下无法满足需求,这个时候就需要重写对应的方法
DRF常用功能
认证
主流认证方式:
Session(会话):客户端请求服务器端,服务端会为这次请求开辟一个内存空间,这个对象就是Session,是为了弥补HTTP无状态,服务端会利用session在客户端存储会话记录进行操作
Token(令牌):用来验证用户身份的凭证,是uid(用户唯一的身份标识)、time(当前时间的时间戳)、sign(签名,以哈希算法压缩成一定长的十六进制字符串)
JWT:与普通Token一样,都是访问资源的令牌
三种认证方式的工作流程图
Session:
![](https://img-blog.csdnimg.cn/img_convert/d9f27ab6ca0d57e57ed4994510a6544d.png)
Token:
![](https://img-blog.csdnimg.cn/img_convert/c625d0292e7e7ab264783d228e282b78.png)
JWT:一帮Token服务端验证token信息要查询数据库验证,JWT验 证token信息不用查询数据库,只需要在服务端使用密 钥效验
![](https://img-blog.csdnimg.cn/img_convert/e1fa830e16ec364243eaafb61abb4063.png)
cookie 和 session 的区别
存储方式:cookie 数据存放在客户的浏览器上,session 数据放在服务器上;
安全性:cookie 是本地存储,不是很安全,别人可以分析存放在本地的 cookie 并进行欺骗;
存储大小:很多浏览器限制单个 cookie 保存的数据不能超过4K,一个站点最多保存20个cookie,session 没有类似的限制;
生存周期:cookie 可设置为长时间保持,Session 一般失效时间较短,一般客户端关闭 session 就会失效
DRF 四种认证方式与权限
• BasicAuthentication:基于用户名和密码的认证,适用于测试 • SessionAuthentication:基于Session的认证 • TokenAuthentication:基于Token的认证 • RemoteUserAuthentication:基于远程用户的认证 DRF支持权限: • IsAuthenticated:只有登录用户才能访问所有API • AllowAny:允许所有用户 • IsAdminUser:仅管理员用户 • IsAuthenticatedOrReadOnly:登录的用户可以读写API,未登录用户只读
Session认证配置
1 在settings.py所有视图(全局)启用认证:
# DRF配置
REST_FRAMEWORK = {
# 认证
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
],
# 权限
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
2 视图级别设置
from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ModelViewSet
class UserView(ModelViewSet):
queryset = User.objects.all() # 指定操作的数据
serializer_class = UserSerializer # 指定序列化器
authentication_classes = [SessionAuthentication]
permission_classes = [IsAuthenticated]
Token 认证配置
1 安装
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'myapp',
'myapp_api',
'Association_table',
'rest_framework.authtoken' #token认证
]
2 启用Token认证
REST_FRAMEWORK = {
# 认证
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
# 权限
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}
3 生成数据库表
python manage.py migrate
4 、配置Token认证接口URL