首页 > 其他分享 >视图集/路由自动生成

视图集/路由自动生成

时间:2023-02-06 20:26:28浏览次数:37  
标签:get ViewSetMixin 视图 生成 图集 path 路由 view

9个视图子类

在此文件中 from rest_framework.generics 有九个视图子类 功能分别如下

9个视图子类---视图类,不需要额外继承GenericAPIView,只需要继承9个中其中某个,就会有某个或某几个接口

CreateAPIView                      新增数据接口    post
ListAPIView                        获取全部数据    get
RetrieveAPIView                    获取单个数据    get
DestroyAPIView                     删除单个数据    delete
UpdateAPIView                      修改单个数据    put
ListCreateAPIView                  获取全部和新增数据  get post
RetrieveUpdateAPIView              查询单个和修改单个  get put
RetrieveDestroyAPIView             查询单个和删除单个  get delete
RetrieveUpdateDestroyAPIView       查询、修改、删除

## 路由
urlpatterns = [
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>/', views.BookView.as_view()),
]

# 视图类
class BookView(ListCreateAPIView):  # 查询所有,新增一个
    queryset = Book.objects.all()
    serializer_class = BookSerializer


# 新增一个,修改一个,删除一个
class BookDetailView(RetrieveUpdateDestroyAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

视图集

1.0版本 视图类ModelViewSet与路由层.as_view({'get': 'list'})搭配使用

from rest_framework.viewsets import ModelViewSet

class BookView(ModelViewSet):  # 继承了这个以后就相当于拥有了5个功能
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    
重点,一旦继承了ModelViewSet那路由写法就要改变为
   path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'})),
   path('books/<int:pk>/', views.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    
 # 通过键值对来 判断 什么请求方式 执行 什么方法

ModelViewSet分析

这个类又继承了 5个视图扩展类 + GenericViewSet 这个类 
GenericViewSet 这个类 又继承了GenericAPIView ViewSetMixin
所以 ModelViewSet 可以拥有 5个功能 

但是导致我们更改url写法的是ViewSetMixin

ViewSetMixin分析

ViewSetMixin重写了as_view方法 所以 以后配置路由变为了
views.BookView.as_view({'get': 'list', 'post': 'create'})
这样当路由请求来的时候 其实是执行了ViewSetMixin的as_view方法
 @classonlymethod
    def as_view(cls, actions=None, **initkwargs):
        # 如果没有传actions,直接抛异常,路由写法变了后,as_view中不传字典,直接报错,actions就是路由里面填写的字典 
        if not actions:
            raise TypeError("The `actions` argument must be provided when "
                            "calling `.as_view()` on a ViewSet. For example "
                            "`.as_view({'get': 'list'})`")
        def view(request, *args, **kwargs):
            self = cls(**initkwargs)
            self.action_map = actions
            for method, action in actions.items():
              # 循环对我们传入的字典解压赋值
              # method = get    action = list
                handler = getattr(self, action)
                # 通过反射视图类中action对应的方法
                # handler就是视图类中的list方法
                setattr(self, method, handler)
								# 反射修改,把method:get的请求方式变为了执行list方法
            return self.dispatch(request, *args, **kwargs)
        # 去除了csrf校验
        return csrf_exempt(view)

#  ViewSetMixin的as_view方法的本质是执行了 view方法
            

总结

'''
from rest_framework.viewsets下有这几个类
ModelViewSet:5个试图扩展类+ViewSetMixin+GenericAPIView
ReadOnlyModelViewSet::2个试图扩展类+ViewSetMixin+GenericAPIView   只读的两个
ViewSetMixin:魔法,重新了as_view,只要继承他,以后路由写法变成了映射方法
ViewSet:ViewSetMixin+ APIView
GenericViewSet:ViewSetMixin+ GenericAPIView
'''

只要是继承了ViewSetMixin的视图类,路由写法都变为了需要(重写了as_veiw)
actions就是我们传入的字典,通过反射来控制 访问方式执行不同的功能
以后视图类中的方法名,可以任意命名,只要在路由中做好映射即可

eg:
path('user/', views.UserView.as_view({'get': 'login', 'post': 'register'}))

class UserView(GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def login(self,request):
        return Response({'code':'100','msg':'登录成功'})
    
    def register(self,request):
      	pass
# 视图类中的方法名,可以任意命名,只要在路由中做好映射即可



# 如果是跟数据库无关的功能接口 例如 短信验证码 等 尽量使用ViewSet

path('msg/<int:pk>/', views.SendView.as_view({'post': 'send_sms'}))
from rest_framework.viewsets import ViewSet

 class SendView(ViewSet):
     def send_sms(self, request,pk):
         print(pk)
         phone = request.query_params.get('phone')
         # 手机号,从哪去,假设get请求,携带了参数
         print('发送成功,%s' % phone)
         return Response({'code': 100, 'msg': '发送成功'})
        
# 以后,你想继承APIView,但是想变路由写法【视图类中方法名任意命名】,要继承ViewSet
# 以后,你想继承GenericAPIView,但是想变路由写法【视图类中方法名任意命名】,要继承GenericViewSet

路由系统 自动生成

# drf 由于继承ViewSetMinxin类,路由写法变了
	-原生+drf,以后的路由写法,可能会有如下情况(三种情况)
    	-path('books/', views.BookView.as_view()
      -path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'}))
       -自动生成
            

如何自动生成路由 -------------------------------------------
#需要 继承ModelViewSet后,路由可以自动生成
            
from rest_framework.routers import SimpleRouter,DefaultRouter
            
routers = SimpleRouter()
# 1.通过导入的生成路由的类产生对象
routers.register('user', views.UserView, 'user')
# 2.向对象内注册一个路由 三个参数分别为 路由的地址  路由关联的视图类 路由别名
# 会自动生成 https//127.0.0.1:8000/user/     https//127.0.0.1:8000/user/<int:pk>
            
urlpatterns = [
    path('admin/', admin.site.urls),
]

urlpatterns = urlpatterns + routers.urls
#3.将自动生成的路由添加到django路由中
            
 
SimpleRouter与DefaultRouter的区别是:DefaultRouter会多附带一个默认的api根视图 返回一个包含所有列表视图的超链接响应数据

一般都使用SimpleRouter

include写路由

from django.urls import path, include
# 导入该模块

from rest_framework.routers import SimpleRouter,DefaultRouter
            
routers = SimpleRouter()
routers.register('user', views.UserView, 'user')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),]


优点:可以自定义路径前缀  建议使用


底层实现:
 -本质是自动做映射,能够自动成的前提是,视图类中要有 5个方法其中的某一个或者多个
           get--->list
           get---->retrieve
           put---->update
           post---->create
           delete---->destory
所以需要搭配视图类继承-ModelViewSet或ReadOnlyModelViewSet或
viewsetMixin+9个视图子类/ViewSetMixin+GenericAPIView+5个试图扩展类
才可以自动生成


eg: class UserView(ViewSetMixin,ListAPIView,RetrieveAPIView):
  # 该接口只能读数据
    queryset = User.objects.all()
    serializer_class = UserSerializer

标签:get,ViewSetMixin,视图,生成,图集,path,路由,view
From: https://www.cnblogs.com/moongodnnn/p/17096584.html

相关文章

  • 视图层与路由系统
    视图层两个视图基类APIViewGenericAPIView5个视图扩展类fromrest_framework.mixinsimportCreateModelMinin,UpdateModelMixin,DestroyModelMixin,......
  • def基本类 自动化路由 以及action装饰器
    今日内容总结九个视图子类#两个视图基类#五个视图扩展类#九个视图子类--->视图类,不需要额外继承GenericAPIView,只需要继承九个中其中某个,就会有某个或某几个接口......
  • 视图组件与路由组件
    9个视图子类两个视图基类(是视图类):APIView,GenericAPIView五个视图扩展类(不是视图类,需要配合使用):CreateModelMixin,ListModelMixin,RetrieveModelMixin,UpdateMod......
  • drf视图类 视图基类、视图扩展类、视图子类、视图集以及路由类
    drf视图类视图基类、视图扩展类、视图子类、视图集两个视图基类APIView这个视图类在前文已经介绍过了,web常见5个接口--APIView的最后有提到:APIView也是继承了django......
  • React中使用路由
     安装:npminstallreact-router-domlocalforagematch-sortersort-by 声明router当安装好路由后就需要在main.js中声明以便可以引入importrouterfrom"./ro......
  • JavaDoc生成文档
    JavaDoc生成文档1、单击Tools-GenerateJavaDoc2、选择要生成文档的类或包,存放路径,设置字符格式,单击OK3、进入存放JavaDoc文件夹,点击index.html即可看生成的JavaDoc......
  • 【Appium】python利用Template生成对象模板_appium_元素定位/操作
    UI自动化中用PageObject设计模式就会发现page元素定位代码基本重复,复制黏贴,修改,所以就想到运用模板方式,批量生成page,同理也能批量生成handle。有模板,利用配置文件ini获取......
  • 1 9 个视图子类 、2 视图集、3 路由系统、4 认证组件
    目录19个视图子类2视图集2.1通过ModelViewSet编写5个接口2.2通过ReadOnlyModelViewSet编写2个只读接口2.3ViewSetMixin源码分析2.4fromrest_framework.viewsets包......
  • 9 个视图子类、视图集、 路由系统、认证组件
    目录1.9个视图子类2视图集2.1通过ModelViewSet编写5个接口2.3ViewSetMixin源码分析2.4fromrest_framework.viewsets包下的类2.5视图层大总结3路由系统3.1自动生成......
  • jmeter+ant生成测试报告
    一、安装ant1、ant下载地址:http://ant.apache.org/,解压到某个目录。2、添加环境变量:ANT_HOME,指向解压后的根目录,如D:\软件工具包\apache-ant-1.9.16-bin\apache-ant-1.9.......