视图层总结
视图集
ModelViewSet -视图类:GenericAPIView - 映射:list create retrieve update destroy CreateModelMixin,ListModelMixin,UpdateModelMixin,DestroyModelMixin,RetrieveModelMixin -路由写法变了:ViewSetMixin 只要继承它,路由写法变了 -分析:ViewSetMixin 不是视图类,支持路由映射的写法,核心原理是重写了as_view -请求来了 原来:执行 APIView的---》as_view内的 view(request) 原来:执行 ViewSetMixin的---》as_view内的 view(request) @classonlymethod def as_view(cls, actions=None, **initkwargs): # actions={'get': 'list', 'post': 'create'} def view(request, *args, **kwargs): self = cls(**initkwargs) # self 是BookView 视图类的对象 self.action_map = actions for method, action in actions.items(): # method:get action:list # 去视图类的对象中 self中 反射list方法---》有--》 # handler 就是 BookView的对象中得list方法 handler = getattr(self, action) # 反射,设置值---》把method:get,设置成了 list #BookView类的对象,以后get方法就是list方法 setattr(self, method, handler) # 根据请求方式执行跟请求方式同名的方法 get请求---》get方法---》list return self.dispatch(request, *args, **kwargs) -ViewSetMixin的总结--》只要继承它 -以后路由写法as_view必须传字典---》映射关系 -什么请求方式---》执行视图类中什么方法 的映射关系 #2 ViewSetMixin类--》路由写法变了的 -源码分析 #3 ViewSet:以后想继承APIView,但是路由写变了,就继承它 #4 GenericViewSet:以后想继承GenericViewSet,但是路由写变了,就继承它 #5 ReadOnlyModelViewSet:只读 -视图类:GenericAPIView - 映射:list retrieve :只查询,查询所有和查询单条ListModelMixin,RetrieveModelMixin -路由写法变了:ViewSetMixin
————————————————————
视图层: # 两个视图基类 APIView GenericAPIView # 5个视图扩展类---》不是视图类,必须结合GenericAPIView CreateModelMixin:create---》原来咱们post中得代码,新增 ListModelMixin:list---》原来获取所有 RetrieveModelMixin:retrieve---》原来获取单条 UpdateModelMixin:update--->修改 DestroyModelMixin:destroy--》删除 # 9个视图子类 CreateAPIView ListAPIView RetrieveAPIView DestroyAPIView UpdateAPIView ListCreateAPIView RetrieveUpdateDestroyAPIView RetrieveDestroyAPIView RetrieveUpdateAPIView # 视图集: ModelViewSet: ReadOnlyModelViewSet: ViewSetMixin:路由写法变了 ViewSet:ViewSetMixin+APIView GenericViewSet:ViewSetMixin+GenericAPIView
小案例选择哪些视图类继承
有很多视图类,不知选哪个? 1 publish的5个接口--ModelViewset # 2 publish的5个接口,获取所有,带code和msg--ModelViewset--》重写list # def list(self, request, *args, **kwargs): # res = super().list(request, *args, **kwargs) # return Response({'code': 100, 'msg': '查询所有成功', 'result': res.data}) # 3 写 查询所有,修改一条,路由写法变了 # ViewSetMixin, GenericAPIView # ListModelMixin,UpdateModelMixin # class BookView(ViewSetMixin, GenericAPIView,ListModelMixin,UpdateModelMixin): # class BookView(GenericViewSet,ListModelMixin,UpdateModelMixin): # queryset = Book.objects.all() # serializer_class = BookSerializer # 路由 # path('books/', views.BookView.as_view({'get': 'list'})), # path('books/<int:id>', views.BookView.as_view({'put': 'update'})), # 4 用户视图类,有登录(login)和注册(register)接口--->第一个跟数据库打交道,第二 做序列化 # class UserView(ViewSet): # def login(self): # pass # def register(self): # pass # path('login/', views.UserView.as_view({'post': 'login'})), # path('register/', views.BookView.as_view({'post': 'register'})), # 5 新增一条图书,路由写法变了 # from rest_framework.generics import CreateAPIView # class BooView(ViewSetMixin,CreateAPIView): # queryset = None # serializer_class = None # #path('books/', views.UserView.as_view({'post': 'create'})), # 6 查询一条和删除 from rest_framework.generics import RetrieveDestroyAPIView # class BooView(RetrieveDestroyAPIView): # class BooView(GenericAPIView,RetrieveModelMixin,DestroyModelMixin): # queryset = None # serializer_class = None
drf之路由
0 视图类没有继承了ViewSetMixin,路由写法跟之前一样 path('books/', views.BookView.as_view()) # 1 只要视图类继承了ViewSetMixin,路由写法必须写成映射的方式 path('books/', views.BookView.as_view({'get': 'list'})), #2 只要视图类继承了ModelViewSet,还可以这么写 1 导入 from rest_framework.routers import SimpleRouter 2 实例化 router = SimpleRouter() 3 注册路径 router.register('books', views.BookView, 'books') 4 加入到路由中 urlpatterns += router.urls 5 list,create,retrieve,destroy,update--->自动映射--》SimpleRouter 3 假设视图类中有个login,如何做对应? from rest_framework.decorators import action class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # list,create,retrieve,destroy,update--->自动映射--》SimpleRouter # 手动映射 #methods=None, 请求方式 # detail=None, 只能写True或False,如果写了false就是不带pk的路径,如果写了True路径带pk # False的情况: http://127.0.0.1:8080/api/v1/books/login/ # True 的情况: http://127.0.0.1:8080/api/v1/books/8/login/ # url_path='login' 路径,会在之前的路径上,拼这个路径,如果不写默认以函数名拼接 # - http://127.0.0.1:8080/api/v1/books/login/ # url_name=None :别名,用做反向解析 @action(methods=['POST'],detail=False,) def login(self,request): return Response('login') 4 总结:以后只要继承ViewSetMixin,就可以使用SimpleRouter方式写路由 1 导入 from rest_framework.routers import SimpleRouter,DefaultRouter 2 实例化 :SimpleRouter,DefaultRouter router = SimpleRouter() 或:认为他们一样即可---》DefaultRouter多一条路径 router = DefaultRouter() 3 注册路径 router.register('books', views.BookView, 'books') 4 加入到路由中: # 方式一:(用这个) urlpatterns += router.urls # 方式二: urlpatterns = [ path('', include(router.urls)), ] 5 list,create,retrieve,destroy,update--->自动映射--》SimpleRouter 6 视图类中自己的方法,再做映射--action装饰器 @action(methods=['POST'],detail=False,) def login(self,request): return Response('login')
认证组件
# 认证---》登录认证
-登录进系统后,以后再访问接口,需要携带登录信息,如果没携带,不允许方法---》这个控制就是认证
-cookie(客户端浏览器上)和session(后端存储的键值对)
# 写个登录
# 后续访问某些接口,携带登录信息--->session--->后端校验(认证组件)
# 认证组件步骤
1 写个认证类,继承BaseAuthentication
2 在类中重写 authenticate,在方法中完成认证,如果通过,返回两个值,如果失败,抛异常
def authenticate(self, request): # 完成对用户的校验 # 当次请求request token = request.query_params.get('token') # 表中校验 user_token = UserToken.objects.filter(token=token).first() # 当前登录用户 if user_token: user = user_token.user # 校验过后,返回两个值 return user, user_token else: raise AuthenticationFailed("token不合法") 3 使用认证类:放在需要登录后才能访问的视图类上 class BookView(ReadOnlyModelViewSet): # 5个接口必须写到正确的token才能访问 authentication_classes = [LoginAuth]
——
视图类-----继承,方法
登录认证实现 及不需登录实现
标签:--,list,视图,---,ViewSetMixin,07days,view,路由,drf From: https://www.cnblogs.com/wzh366/p/17928204.html