首页 > 其他分享 >drf——5个视图扩展类、9个视图子类、视图集、drf之路由

drf——5个视图扩展类、9个视图子类、视图集、drf之路由

时间:2023-05-23 21:35:58浏览次数:29  
标签:return get 子类 self request 视图 路由 drf

5个视图扩展类

# 写5个类(不叫视图类 视图拓展类 需要配合GenericAPIView一起用) 每个类有一个方法 以后想写哪个接口 就继承哪个类即可
from rest_framework.response import Response

####自己封装的5个视图拓展类
class ListModelMixin:
    def list(self,request):
        qs = self.get_queryset()
        ser = self.get_serializer(qs,many=True)
        return Response({'code':100,'msg':'成功','result':ser.data})

class CreateModelMinxin:
    def create(self,request):
        ser = self.get_serializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code':100,'msg':'成功'})
        else:
            return Response({'code':100,'msg':'失败'})

class RetrieveModelMixin:
    def retrieve(self,request,*args,**kwargs):
        qs = self.get_object()
        ser = self.get_serializer(qs)
        return Response({'code':100,'msg':'成功','result':ser.data})

class UpdateModelMixin:
    def update(self,request,*args,**kwargs):
        qs = self.get_object()
        ser = self.get_serializer(qs,data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code':100,'msg':'成功'})
        else:
            return Response({'code': 100, 'msg': '失败'})

class DestroyModelMixin:
    def destroy(self,request,*args,**kwargs):
        qs = self.get_object()
        qs.delete()
        return Response({'code':100,'msg':'成功'})
    
#### drf封装好的
from .models import Book
from .serializer import BookSerializer
from rest_framework.response import Response
from rest_framework.generics import GenericAPIView

from rest_framework.mixins import ListModelMixin,CreateModelMinxin,UpdateModelMinxin,DestroyModelMixin,
RetrieveModelMixin

class BookView(GenericAPIView,ListModelMixin,CreateModelMixin):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    
    def get(self,request):
        return self.list(request)
    
    def post(self,request):
        return self.create(request)
    
class BookDetailView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,
DestroyModelMixin):
    queryset = Book.object.all()
    serializer_class = BookSerializer
    
    def get(self,request,*args,**kwargs):
        return self.retrieve(request,*args,**kwargs)
    
    def put(self,request,*args,**kwargs):
        return self.update(request,*args,**kwargs)
    
    def delete(self,request,*args,**kwargs):
        return self.destroy(request,*args,**kwargs)
# 5个视图扩展类(不是视图类)---》必须配合GenericAPIView及其子类使用---》不能配合APIView使用
# 5个视图扩展类 每一个类中只有一个方法 完成5个接口中的其中一个 想写多个接口 就要继承多个

9个视图子类

'''基于视图子类写接口 9个视图子类--->视图类'''
from rest_framework.generics import ListAPIView,CreateAPIView,RetrieveAPIView,UpdateAPIView,DestroyAPIView
from rest_framework.generics import ListCreateAPIView
from rest_framework.generics import RetrieveUpdateDestroyAPIView
from rest_framework.generics import RetrieveUpdateAPIView
from rest_framework.generics import RetrieveDestroyAPIView
# from rest_framework.generics import UpdateDestroyAPIView  # 这个没有

# ModelViewSet:
	继承它后 只需要在视图类中写两行
    	queryset = Book.objects.all()
        serializer_class = BookSerializer
    配置路由,5个接口都有了
    	path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
    	path('books/<int:pk>/', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
   ######
	def list(self, request, *args, **kwargs):
        res = super().list(request,*args,**kwargs)
        return Response({'code': 100, 'msg': '成功', 'data': res.data})
	可以重写父类中的方法 但是一定不能用self. 必须使用super() 否则会递归
        
# 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
                    hander = getattr(self,action)
                    # 通过反射:setattr(BookView的对象,'get',list方法)
                    setattr(self,method,handler)
                # APIView的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个视图子类),必须放在视图类之前
"""

视图集

# 两个视图基类
	APIView
    GenericAPIView
# 5个视图扩展类(不是视图类 需要配合GenericAPIView及其子类使用)

# 9个视图子类

# 视图集:
	ModelViewSet:5个接口的
    ReadOnlyModelViewSet:两个接口 list和retrieve
    ViewSetMixin:魔法 不能单独使用,必须配合视图类用 路由写法变了
    ViewSet:ViewSetMixin + APIView 以后想继承APIView 但是想路由写法变化 视图类中方法可以任意命名
    GenericViewSet:ViewSetMixin + GenericAPIView 以后想继承GenericAPIView 但是想路由写法变化 视图类中方法可以任意命名

drf之路由

# 路由的写法有多种
	原始写法
    映射的写法:path('books/',BookView.as_view({'get':'list','post':'create'}))
    自动生成路由
    
# 自动生成路由
	必须要继承ViewSetMixin及其子类的视图类,才能用
    继承了 5个视图扩展类+ViewSetMixin的视图类,能自动生成路由(ModelViewSet)
		跟咱们写的这个是一样的
        path('books/', BookView.as_view({'get': 'list', 'post': 'create'})),
        path('books/<int:pk>/', BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}))
   
'''第一步 导入一个路由类'''
from rest_framework.routers import SimpleRouter
'''第二步 实例化得到对象'''
router = SimpleRouter()
'''第三步 注册路由(视图类) 第一个参数是前缀 第二个参数是视图类 第三个参数是别名'''
router.register('books',BookView,'books')
# http://127.0.0.1:8000/api/v1/books/books/
# 第一个books是注册路由时的前缀 第二个books是action装饰器的url_path参数
'''第四部 加入到路由中'''
# 4.1 方式一
# urlpatterns += router.urls
# 4.2 方式二
# 使用include  path('api/v1/', include(router.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):
                return Response('你好')
        # 路由
        router.register('lqz',SMSView,'lqz')
        # 路径是:http://127.0.0.1:8000/api/v1/lqz/lqz/  第一个是前缀第二个是url_path的参数 如果没有就是函数名
    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根视图,返回一个包含所有列表视图的超链接响应数据(提示你可以访问哪些路径)。

标签:return,get,子类,self,request,视图,路由,drf
From: https://www.cnblogs.com/XxMa/p/17421907.html

相关文章

  • 视图(Views)- Yii2 权威指南
    视图 ¶创建视图渲染视图布局使用视图组件视图事件渲染静态页面最佳实践视图是 MVC 模式中的一部分。它是展示数据到终端用户的代码,在网页应用中,根据视图模板来创建视图,视图模板为PHP脚本文件,主要包含HTML代码和展示类PHP代码,通过yii\web\View应用组件来管理,该组......
  • iOS UIView如何管理它的子视图
    didMoveToWindow 通知接收者它一斤给添加到窗口中 -(void)didMoveToWindow 讨论 默认实现不做任何事情;子类可以重写这个方法来做特殊的实现 窗口的属性有可能是nil当这个方法调用的时候,这表明接收者并不属于当然任何一个窗口。这个只发生在接收者从它的父视图上移......
  • drf——自定义权限
    第一步:创建自定义权限首先,需要创建自定义权限类以实现企业黑名单功能。在你的permissions.py文件中创建一个新的类,例如:fromrest_frameworkimportpermissionsclassBlacklistPermission(permissions.BasePermission):message='Youraccounthasbeenblacklisted.'......
  • drf——反序列化校验源码(了解)、断言、drf之请求和响应、视图之两个视图基类
    1.模块与包#模块与包 模块:一个py文件被别的py文件导入使用,这个py文件称之为模块,运行的这个py文件称之为脚本文件包:一个文件夹下有__init__.py#模块与包的导入问题'''1.导入模块有相对导入和绝对导入,绝对导入的路径是从环境变量开始的2.导入任何模块,如果......
  • drf自动生产路由
    自动生产路由#ReadOnlyModelViewSet:两个接口,list和retrievefromrest_framework.viewsetsimportReadOnlyModelViewSetclassBookLIstretrieveView(ReadOnlyModelViewSet):queryset=Book.objects.all()serializer_class=Bookserializers#ViewSetMixin:魔......
  • 5个视图扩展类,9个视图子类,视图集,drf之路由
    5个视图扩展类:1from.modelsimportBook2from.serializerimportBookSerialzier3fromrest_framework.responseimportResponse4fromrest_framework.genericsimportGenericAPIView56fromrest_framework.mixinsimportListModelMixin,CreateModelMixi......
  • 2个视图基类,5个视图扩展类,9个视图子类,视图集,自动生成路由
    考p.name改变的是p对象自己的属性所以p.name='彭于晏'p1.name=lqz15个视图扩展类#写5个类(不叫视图类,视图扩展类,需要配合GenericAPIView一起用),每个类有一个方法,以后想写哪个接口,就继承哪个类即可from.modelsimportBookfrom.serializerimportBookSerialzierf......
  • 两个视图基类GenericAPIView,APIView
    基于两个视图基类GenericAPIView,APIViewclassBookserializers(serializers.ModelSerializer):#name=serializers.CharField()#price=serializers.CharField()#publish_id=serializers.CharField(write_only=True)#Authors=serializers.ListFie......
  • MFC视图切换大全总结
    单纯视图之间的切换单文档多视图切换是我在学习MFC中遇到的一个老大难问题,在今天总算是一一破解了。我觉得视图切换分为三个等级,第一是在未切分窗格的情况下切换视图类;第二是在分割窗格的一个窗格内实行视图切换;第三是在分割窗格和未分割之间的切换和视图切换。在MFC创建SDI的伊......
  • mysql基础_视图
    介绍MySQL视图(View)是一种虚拟存在的表,同真实表一样,视图也由列和行构成,但视图并不实际存在于数据库中。行和列的数据来自于定义视图的查询中所使用的表,并且还是在使用视图时动态生成的。优点定制用户数据,聚焦特定的数据简化数据操作提高数据的安全性共享所需数据......