DRF 视图
from django.shortcuts import render
# Create your views here.
from rest_framework.response import Response # DRF 中的响应
from students.serializers import StudentModelSerializer # 序列化器
from students.models import Student # 模型
from rest_framework.views import APIView # 基础视图类
from rest_framework.generics import GenericAPIView # 通用视图类
from rest_framework import status # 响应状态码code
'''APIView 视图类'''
'''
作用:
1. 传入Rest_Framework中的Request对象 不是Django中的HttpRequest对象
2. 传入Rest_Framework中的Response对象 不是Django中的HttpResponse对象
3. APIException 异常会被捕获到,处理成适合响应的信息
4. 在dispatch() 路由分发前,会对请求进行身份验证,权限检查,流量控制
属性
authentication_classes : 列表/元组,身份认证
permissoin_classes : 列表/元组,权限检查类
throttle_classes : 列表/元组, 流量控制类
'''
class StudentAPIView(APIView):
def get(self, request):
student_list = Student.objects.all()
serializer = StudentModelSerializer(instance=student_list, many=True)
return Response(serializer.data)
def post(self, request):
data = request.data
serializer = StudentModelSerializer(data=data, )
serializer.is_valid(raise_exception=True) # 不强制校验错误!
ret = serializer.save()
if ret:
st = status.HTTP_201_CREATED
else:
st = status.HTTP_400_BAD_REQUEST
return Response(serializer.data, status=st)
'''GenericAPIView 通用视图类 '''
'''
属性:
queryset : 指定列表视图的查询数据集合
serializer_class : 指定视图使用的序列化器
pagination_class : 分页控制类
filter_backends : 过滤
lookup_field : 查询单一数据对象 时使用的条件字段,默认值是'pk'
loop_url_kwarg : 查询单一数据时URL中的参数关键名称,默认与lookup_field一致
方法:
get_queryset(self) : 获取所有数据
get_serializer_class(self) : 调整序列化器类
get_serializer(self,args,*kwargs) : 获取序列化器对象
get_object(self) : 获取一条数据
'''
class StudentGenericAPIView(GenericAPIView):
'''
# 必须指定两个参数
1. 序列化器
2. 数据集
# 备注: 对视图类并没有简写 , 需要结合视图扩展类
'''
serializer_class = StudentModelSerializer
queryset = Student.objects.all()
def get(self, request):
serializer = self.serializer_class(instance=self.get_queryset(), many=True)
return Response(serializer.data)
def post(self, request):
data = request.data
serializer = self.serializer_class(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data)
'''
# 通用视图类 + 视图混合类
# 衍生出 四种:
Createmodelmixin 添加一条数据
Listmodelmixin 获取所有数据
Retrievemodelmixin 获取一条数据
Destorymodelmixin 删除一条数据
Updatemodelmixin 更新一条数据
'''
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin
class StudentGeneralModelMixinAPIView(GenericAPIView, CreateModelMixin, ListModelMixin, DestroyModelMixin):
serializer_class = StudentModelSerializer
queryset = Student.objects.all()
def get(self, request):
'''
# 获取所有数据
:param request:
:return:
'''
return self.list(request)
def post(self, request):
'''
# 保存数据
:param request:
:return:
'''
return self.create(request)
def delete(self, request, pk):
'''
# 删除一条数据
:param request:
:param pk:
:return:
'''
return self.destroy(request, pk)
'''
### 基于 通用视图类和 视图混合类衍生
CreateAPIView 创建一套数据
ListAPIView 获取所有数据
RetrieveAPIView 获取一条数据
DestoryAPIView 删除一条数据
UpdateAPIView 更新一条数据
RetrieveUpdateAPIView 更新一条数据
RetrieveUpdateDestoryAPIView 更新或删除一条数据
'''
路由
"""DrfDemo URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from . import views
urlpatterns = [
path('stu_api_view/',views.StudentAPIView.as_view()),
path('stu_generic_api_view/',views.StudentGenericAPIView.as_view()),
re_path('^stu_generic_model_mixin_api_view/$',views.StudentGeneralModelMixinAPIView.as_view()),
re_path('^stu_generic_model_mixin_api_view/(?P<pk>\d+)/$',views.StudentGeneralModelMixinAPIView.as_view()),
]
DRF集合
from django.shortcuts import render
# Create your views here.
from rest_framework.response import Response
from students.models import Student
from students.serializers import StudentModelSerializer
from rest_framework.viewsets import ViewSet
'''
# 基类视图集 : ViewSet
特点:
1. 需要手动指定执行方法 ,如:获取一条数据/获取多条数据
2. 不同的路由需要在as_view() 方法中指定:http请求方法 反射到 不同的函数
'''
class StudentAPIViewSet(ViewSet):
def get_one_data(self, request, pk):
'''
# 查询一条数据
:param request:
:param pk:
:return:
'''
student_list = Student.objects.get(pk=pk)
serializer = StudentModelSerializer(instance=student_list)
return Response(serializer.data)
def get_all_data(self, request):
'''
# 查询所有数据
:param request:
:return:
'''
student_list = Student.objects.all()
serializer = StudentModelSerializer(instance=student_list, many=True)
return Response(serializer.data)
'''
# 通用视图集合 GenericViewSet
特点:
1. 提供了 序列化器 和 模型 , 为了 模型视图集 做铺垫
2. 需要 手动维护 处理的函数
2. 需要手动在as_view路由分发函数, 指定 http请求方法 对应的处理视图函数
'''
from rest_framework.viewsets import GenericViewSet
class StudentGenericViewSet(GenericViewSet):
serializer_class = StudentModelSerializer
queryset = Student.objects.all()
def retrieve(self, request, pk):
'''
查询一条
:param request:
:param pk:
:return:
'''
student = self.get_object()
serializer = self.get_serializer(instance=student)
return Response(serializer.data)
def list(self, request):
student_list = self.get_queryset()
serializer = self.get_serializer(instance=student_list, many=True)
return Response(serializer.data)
from rest_framework.mixins import CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin
'''
# 通用视图集 和 视图混合类使用
特点:
1. 不需要手动维护 http请求方法对应的 视图处理函数
2. 需要哪个混合类的功能,需要手动继承
'''
class StudentGenericViewSetMixin(GenericViewSet, ListModelMixin, RetrieveModelMixin):
serializer_class = StudentModelSerializer
queryset = Student.objects.all()
def get_top_2(self, request):
student_list = self.get_queryset()[:2]
serializer = self.get_serializer(instance=student_list, many=True)
return Response(serializer.data)
''' 只读视图集 :ReadOnlyModelViewSet
特点:
1. 只提供了 list 和retrieve 2个函数
'''
from rest_framework.viewsets import ReadOnlyModelViewSet
class StudentReadOnlyModelViewSetMixin(ReadOnlyModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
'''
# 模型视图集 StudentModelViewSetMixin
特点:
1. 提供了5个处理函数
'''
from rest_framework.viewsets import ModelViewSet
class StudentModelViewSetMixin(ModelViewSet):
queryset = Student.objects.all()
serializer_class = StudentModelSerializer
### Action : 解决 一个路由和多个处理函数的映射
'''
# 在 视图集中,因为自定义视图方法的名字会各种各样,需要视图获得客户端请求的视图方法名
request.action属性来查看
'''
from rest_framework.decorators import action # 装饰
class StudentAPIViewSetAction(ViewSet):
# 为什么: 用到action,是因为视图集中 存在自定义的方法名, 如果自定义函数较多,则路由会越写越多
# 使用action 通过路由注册的方式,按照drf默认的规则生成 新的路由地址
# action装饰器 使用:
# 1. methods 指定 访问的HTTP请求方法,与flask类似
# 2. detail 表示设置router路由类在生成路由的时候是否要加上 ,主键pk到URL地址栏中
@action(methods=['get'], detail=True)
def get_one_data(self, request, pk):
'''
# 查询一条数据
:param request:
:param pk:
:return:
'''
# print(self.action) # 获取Action:get_one_data ,客户端调用通过HTTP调用到的处理视图函数
student_list = Student.objects.get(pk=pk)
serializer = StudentModelSerializer(instance=student_list)
return Response(serializer.data)
@action(methods=['get'], detail=False)
def get_all_data(self, request):
'''
# 查询所有数据
:param request:
:return:
'''
student_list = Student.objects.all()
serializer = StudentModelSerializer(instance=student_list, many=True)
return Response(serializer.data)
路由
"""DrfDemo URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, re_path
from . import views
urlpatterns = [
# 视图集 中的方法和地址,以及HTTP请求的绑定都是通过as_view()完成的
# 基础视图集合 ViewSet
path('stu_view_set/', views.StudentAPIViewSet.as_view({'get': 'get_all_data'})),
re_path('stu_view_set/(?P<pk>\d+)/', views.StudentAPIViewSet.as_view({'get': 'get_one_data'})),
# 通用视图集合 GenericViewSet
path('stu_generlic_view_set/', views.StudentGenericViewSet.as_view({'get': 'list'})),
re_path('stu_generlic_view_set/(?P<pk>\d+)/', views.StudentGenericViewSet.as_view({'get': 'retrieve'})),
# 通用视图集 GenericViewSet 和 视图混合类 ListModelMixin, RetrieveModelMixin
path('stu_generlic_view_set_mixin/', views.StudentGenericViewSetMixin.as_view({'get': 'list'})),
path('stu_generlic_view_set_mixin/top/', views.StudentGenericViewSetMixin.as_view({'get': 'get_top_2'})),
re_path('stu_generlic_view_set_mixin/(?P<pk>\d+)/', views.StudentGenericViewSetMixin.as_view({'get': 'retrieve'})),
# 只读 视图集 ReadOnlyModelViewSet (包含 ListModelMixin, RetrieveModelMixin 混合类)
path('stu_readonly_view_set_mixin/', views.StudentReadOnlyModelViewSetMixin.as_view({'get': 'list'})),
re_path('stu_readonly_view_set_mixin/(?P<pk>\d+)/',
views.StudentReadOnlyModelViewSetMixin.as_view({'get': 'retrieve'})),
# 模型 视图集 StudentModelViewSetMixin (包含所有混合类)
path('stu_model_view_set_mixin/', views.StudentModelViewSetMixin.as_view({'get': 'list', 'post': 'create'})),
re_path('stu_model_view_set_mixin/(?P<pk>\d+)/',
views.StudentModelViewSetMixin.as_view({'get': 'retrieve', 'delete': 'destroy', 'put': 'update'})),
# ViewSet ====>Action的查看
path('stu_view_set_action/', views.StudentAPIViewSet.as_view({'get': 'get_all_data'})),
re_path('stu_view_set_action/(?P<pk>\d+)/', views.StudentAPIViewSet.as_view({'get': 'get_one_data'})),
]
#### 基于action 装饰器 和 路由类 来生成路由,达到简写的目的
# SimpleRouter 作用: 为视图 生成url路由, 不会生成根目录, <上线使用>
# DefaultRouter 作用: 为视图 生成url路由
from rest_framework.routers import SimpleRouter, DefaultRouter
router = DefaultRouter()
### 注册视图集 ->生成视图集对应的路由方法
# 1. 格式: router.register('路由前缀','视图集类','可选参数:路由别名前缀')
# 2. 访问:
# 访问单一数据 : http://127.0.0.1:8000/viewset/stu_view_set_action_auto/1/get_one_data/
# 访问多条数据 : http://127.0.0.1:8000/viewset/stu_view_set_action_auto/get_all_data/
router.register('stu_view_set_action_auto', views.StudentAPIViewSetAction,'action')
# print(router.urls)
urlpatterns += router.urls