2个视图基类&5个视图mixins扩展类&9个GenericAPIView的视图子类&5个viewsets视图集基类
2个视图基类
APIView
等级最高 但是写起来代码量也最多
# 基于APIView写的view.py
class BookView(APIView):
def get(self, request):
book_obj = models.Book.objects.all()
book_ser = ser.BookModelSerializers(book_obj, many=True)
return Response(book_ser.data)
def post(self, request):
book_ser = ser.BookModelSerializers(data=request.data)
if book_ser.is_valid():
book_ser.save()
return Response(book_ser.data)
else:
return Response({'status': 101, 'msg': '校验失败'})
GenericAPIView(涉及到数据库 用queryset serializer_class 比较方便)
1. 继承自APIVIew,
2. 主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类的执行提供方法支持。
3. 通常在使用时,可搭配一个或多个Mixin扩展类。
# 基于GenericAPIView
class Book2View(GenericAPIView):
queryset = models.Book.objects.all() # 获取对象
serializer_class = ser.BookModelSerializers # 获取序列化对象
def get(self, request):
book_obj = self.get_queryset()
book_ser = self.get_serializer(book_obj, many=True)
return Response(book_ser.data)
def post(self, request):
book_ser = self.get_serializer(data=request.data)
if book_ser.is_valid():
book_ser.save()
return Response(book_ser.data)
else:
return Response({'status': 101, 'msg': '校验失败'})
5个视图扩展类mixins
mixins介绍(CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, ListModelMixin)
1. 提供了几种后端视图(对数据资源进行曾删改查)处理流程的实现,
2. 如果需要编写的视图属于这五种,则视图可以通过继承相应的扩展类来复用代码,减少自己编写的代码量。
3. 这五个扩展类需要搭配GenericAPIView父类,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法。
# 一般都搭配GenericAPIView,直接继承拓展类就能实现每个方法 下面是对比
class Book3View(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = models.Book.objects.all()
serializer_class = ser.BookModelSerializers
# def get(self, request):
# book_obj = self.get_queryset()
# book_ser = self.get_serializer(book_obj, many=True)
# return Response(book_ser.data)
def get(self, request):
return self.list(request)
# def post(self, request):
# book_ser = self.get_serializer(data=request.data)
# if book_ser.is_valid():
# book_ser.save()
# return Response(book_ser.data)
# else:
# return Response({'status': 101, 'msg': '校验失败'})
def post(self, request):
return self.create(request)
9个GenericAPIView的视图子类
GenericAPIView的子类介绍
1. 视图子类,也叫通用视图子类。
2. 继承了GenericAPIView,以及Mixin,真正的实现了几行代码,完成一个视图
3. 其实就是帮你,return了视图中手动return的方法
1)CreateAPIView
提供 post 方法
继承自: GenericAPIView、CreateModelMixin
2)ListAPIView
提供 get 方法
继承自:GenericAPIView、ListModelMixin
3)RetrieveAPIView
提供 get 方法
继承自: GenericAPIView、RetrieveModelMixin
4)DestoryAPIView
提供 delete 方法
继承自:GenericAPIView、DestoryModelMixin
5)UpdateAPIView
提供 put 和 patch 方法
继承自:GenericAPIView、UpdateModelMixin
6)ListCreateAPIView
提供 get、post方法
继承自: GenericAPIView、ListModelMixin、CreateModelMixin
7)RetrieveUpdateAPIView
提供 get、put、patch方法
继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin
8)RetrieveDestroyAPIView
提供 get、delete方法
继承自: GenericAPIView、RetrieveModelMixin、DestroyModelMixin
9)RetrieveUpdateDestoryAPIView
提供 get、put、patch、delete方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestoryModelMixin
# 基于GenericAPIView的9个视图子类
# class Book4View(ListAPIView, CreateAPIView): # 查看所有 添加一个数据
class Book4View(ListCreateAPIView): # 两个直接并一个也可以
queryset = models.Book.objects
serializer_class = ser.BookModelSerializers
# class Book4DetailView(RetrieveAPIView, UpdateAPIView, DestroyAPIView): # 查看一条数据 更新数据 删除数据
class Book4DetailView(RetrieveUpdateDestroyAPIView): # 三个并一个也可以
queryset = models.Book.objects
serializer_class = ser.BookModelSerializers
5个Viewsets视图集基类
1、源码分析ViewSetMixin
# 重写了as_view
# 核心代码(所以路由中只要配置了对应关系,比如{'get':'list'}),当get请求来,就会执行list方法
for method, action in actions.items():
# method:get
# action:list
handler = getattr(self, action)
#执行完上一句,handler就变成了list的内存地址
setattr(self, method, handler)
#执行完上一句 对象.get=list
#for循环执行完毕 对象.get:对着list 对象.post:对着create
2、5个Viewsets视图类
class ViewSet(ViewSetMixin, views.APIView):
"""
The base ViewSet class does not provide any actions by default.
"""
pass
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
"""
The GenericViewSet class does not provide any actions by default,
but does include the base set of generic view behavior, such as
the `get_object` and `get_queryset` methods.
"""
pass
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `list()` and `retrieve()` actions.
"""
pass
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
3、继承ViewSetMixin的视图类(可以自定义名称了,需要配置action)
# views.py方式一
from rest_framework.viewsets import ViewSetMixin
class Book6View(ViewSetMixin,APIView):
"""
ViewSetMixin 一定要放在APIVIew前 继承的查找顺序先找前边的
ViewSetMixin,APIView 里面都有 as_view()方法 但是我们要使用重写的as_view()方法
所以要先去ViewSetMixin里面找
"""
def get_all_book(self,request):
print('我可以自定义名称喽')
book_list = Book.objects.all()
book_ser = BookSerializer(book_list, many=True)
return Response(book_ser.data)
# urls.py
# 继承ViewSetMixin的视图类,路由可以改写成这样
path('books6/', views.Book6View.as_view(actions={'get': 'get_all_book'})),
# views.py方式二
# 装饰器,放在被装饰的函数上方,method:请求方式,detail:是否带pk
from rest_framework.decorators import action # 装饰器
class BookView(ModelViewSet):
queryset = models.Book.objects
serializer_class = ser.BookModelSerializer
# methods第一个参数传入一个列表 列表中放请求方式
# ^books/get_2/$ [name='book-get-2'] 当向这个地址发送get请求时,会执行下面的函数
# detail 传布尔值 默认写False 当改成True时
# ^books/(?P<pk>[^/.]+)/$ [name='book-detail'] 路由会带上pk
@action(methods=['get'], detail=False)
def get_2(self, request):
book = self.get_queryset().all()[:2]
book_ser = self.get_serializer(book, many=True)
return Response(book_ser.data)
# urls.py
path('books/', views.BookView.as_view(actions={'get': 'get_2'})),
# views.py方式三
class LoginView(ViewSet):
@action(methods=['POST'], detail=False)
def login(self, request, *args, **kwargs):
ser = serializer.UserSerializer(data=request.data)
if ser.is_valid():
token = ser.context.get('token')
# ser.context['user']拿到的是user对象
username = ser.context.get('user').username
return APIResponse(token=token, username=username)
else:
return APIResponse(code=0, msg=ser.errors)
# urls.py 自动生成路由
from django.urls import path, re_path, include
from . import views
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
# 为什么这里不写域名 是因为你视图函数中已经定义了login这个函数他自己就传过去了 如果在写就成了/login/login
router.register('', views.LoginView, 'login')
urlpatterns = [
path('', include(router.urls))
]
ModelViewSet了解一般不用,封装程度太高
# 基于ModelViewSet写五个接口 终极大招
path('books5/', views.Book5View.as_view(actions={'get': 'list', 'post': 'create'})), # 当路径匹配到又是get请求 就会执行ListModelMixin方法
re_path('books5/(?P<pk>\d+)/', views.Book5View.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
# 基于ModelViewSet写五个接口 终极大招
from rest_framework.viewsets import ModelViewSet
"""
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet)
直接继承五个大类方法 并且重写了as_view方法
"""
class Book5View(ModelViewSet): # 一个直接写完五个接口
queryset = models.Book.objects
serializer_class = ser.BookModelSerializers
标签:GenericAPIView,ser,框架,get,self,视图,book,class,DRF
From: https://www.cnblogs.com/piggthird/p/17884689.html