5个视图扩展类:
1 from .models import Book 2 from .serializer import BookSerialzier 3 from rest_framework.response import Response 4 from rest_framework.generics import GenericAPIView 5 6 from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, \ 7 RetrieveModelMixin 8 9 10 class BookView(GenericAPIView, ListModelMixin, CreateModelMixin): 11 queryset = Book.objects.all() 12 serializer_class = BookSerialzier 13 14 def get(self, request): 15 return self.list(request) 16 17 def post(self, request): 18 return self.create(request) 19 20 21 22 class BookDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): 23 queryset = Book.objects.all() 24 serializer_class = BookSerialzier 25 26 def get(self, request, *args, **kwargs): 27 return self.retrieve(request, *args, **kwargs) 28 29 def put(self, request, *args, **kwargs): 30 return self.update(request, *args, **kwargs) 31 32 def delete(self, request, *args, **kwargs): 33 return self.destroy(request, *args, **kwargs)
总结:
5 个视图扩展类--->不是视图类---》必须配合GenericAPIView及其子类使用---》不能配合APIView使用
5个视图扩展类,每一个类中只有一个方法,完成5个接口中的其中一个,想写多个接口,就要继承多个
9个视图子类:
ListAPIView:查所有,相当于get
CreateAPIView:增加,相当于post
UpdateAPIView:修改,相当于put
RetrieveAPIview:查单个,相当于get
DestroyAPIView:删除,相当于delete
ListCreateAPIView:增加和查所有--------->get+post
RetrieveUpdateAPIView:查单个和修改-------------->get+put
RetrieveDestroyAPIView:查单个和删除---------------->get+delete
RetrieveUpdateDestroyAPIView:查单个,修改和删除------------------->get+put+delete
from rest_framework.generics import ListAPIView,CreateAPIView,UpdateAPIView,RetrieveAPIView,DestroyAPIView from rest_framework.generics import ListCreateAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView,RetrieveUpdateDestroyAPIView class BookView(ListCreateAPIView): queryset = Book.objects.all() serializer_class = BookSerializer class BookDetailView(RetrieveUpdateDestroyAPIView): queryset = Book.objects.all() serializer_class = BookSerializer
视图集:
ModelViewSet:
-继承它后,只需要在视图类中写两行
queryset = Book.objects.all()
serializer_class = BookSerialzier
-配置路由,5个接口都有了
path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
path('books/<int:pk>/', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
ModelViewSet 源码分析
-继承了:
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin
GenericViewSet
-ViewSetMixin :没有见过,重写了 as_view
-GenericAPIView
-只要继承了ModelViewSet,路由写法变了,谁控制它变的:ViewSetMixin
ViewSetMixin 如何控制路由写法变了?
-BookView.as_view 是在执行,其实是ViewSetMixin的as_view
@classonlymethod
def as_view(cls, actions=None, **initkwargs):
#我们传入的 actions={'get': 'list', 'post': 'create'}
def view(request, *args, **kwargs):
self = cls(**initkwargs)
for method, action in actions.items():
# method:get
# action:list
# 通过反射,self是BookView的对象,取BookView对象中反射list
handler = getattr(self, action)
# 通过反射:setattr(BookView的对象,'get',list方法)
setattr(self, method, handler)
# APIViwe的dispatch
return self.dispatch(request, *args, **kwargs)
return csrf_exempt(view)
总结:
1 只要继承了ViewSetMixin及其子类,路由写法就变了,必须传actions参数
2 变成映射关系了:
path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
3 以后,只要是books路由匹配成功的get请求,就会执行视图类BookView的list方法
4 以后视图类中的方法名,可以随意命名
5 这个类,必须配合视图类使用(APIView,GenericAPIView,9个视图子类),必须放在视图类之前
view层:
url层:
视图集:
ModelViewSet:5个接口的
ReadOnlyModelViewSet:两个接口,list和retrieve
ViewSetMixin:魔法,不能单独使用,必须配合视图类用,路由写法变了
ViewSet:ViewSetMixin+APIView,以后想继承APIView,但是想路由写法变化,视图类中方法可以任意命名
GenericViewSet:ViewSetMixin+GenericAPIView,以后想继承GenericAPIView,但是想路由写法变化,视图类中方法可以任意命名
drf之路由:
自动生成路由
-必须要继承ViewSetMixin及其子类的视图类,才能用
-继承了 5个视图扩展类+ViewSetMixin的视图类,能自动生成路由
-跟咱们写的这个是一样的
-path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
-path('books/<int:pk>/', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
第一种方式:
第二种加入总路由的方式:
导入include模块:from django.urls import include
在urlpatterns中加入:include(rounter.urls)
自动生成路由
1 继承了 5个视图扩展类+ViewSetMixin的视图类,能自动生成路由(get:list,get:retrieve..)
2 我们自己命名的: 方法名:login send_sms,需要使用装饰器来做
视图类:
class SMSView(ViewSet):
@action(methods=['GET'], detail=False, url_path='lqz', url_name='lqz')
def lqz(self, request):
路由
router.register('lqz',SMSView,'lqz')
路径是:http://127.0.0.1:8000/api/v1/lqz/lqz/
3.action装饰器的参数
methods:请求方式
detail:一个True,一个False,用True,表示生成详情的路径 <int:pk>
# True,books/1/方法名/
# False,books/方法名/
url_path:路径名字,需要加上前面的路径一起,如果不加,默认以函数名作为路径名
url_name:反向解析使用的名字(用的不多)
路由类,有两个,用法完全一致,区别是DefaultRouter生成的路径多
SimpleRouter :用的最多
DefaultRouter
DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。
标签:BookView,get,子类,self,request,视图,路由,drf From: https://www.cnblogs.com/Hao12345/p/17421682.html