【Django学习】(十四)自定义action_router

之前我们的视图类可以继承GenericViewSet或者ModelViewSet,我们不用再自定义通用的action方法,但是有时候我们需要自定义action,我们该如何设计呢?

自定义action

1、手写视图逻辑

1.1、先在视图集里自定义action方法,名称为names

class ProjectsViewSet(viewsets.ModelViewSet):# 指定当前类视图需要使用的查询集queryset = ProjectsModel.objects.all()# 指定当前类视图需要使用的序列化器类serializer_class = ProjectModelSerializer# lookup_field = 'Id'# 声明需要使用的引擎类filter_backends = [filters.SearchFilter,filters.OrderingFilter]# 定义需要过滤的字段search_fields = ['name', 'id']# 定义需要排序的字段ordering_fields = ['id', 'name']# 声明需要使用的分页引擎pagination_class = PageNumberPagination@action(methods=['GET', 'POST'], detail=False)def names(self, request, *args, **kwargs):qs = self.get_queryset()lst = []for obj in qs:dict = {'id': obj.id,'name': obj.name,}lst.append(dict)return Response(lst, content_type='application/json')

1.2、在路由表url.py中定义新的路由

urlpatterns = [path('projects/names/',views.ProjectsViewSet.as_view({'get':'names','post':'names'})),
]

 支持get和post请求方式

 

 2、使用序列化器类

2.1创建一个新的序列化器类

class ProjectNameSerializer(serializers.ModelSerializer):class Meta:model = ProjectsModelfields = ('id', 'name')

2.2路由表定义路由

urlpatterns = [path('projects/names/',views.ProjectsViewSet.as_view({'get':'names','post':'names'})),
]

仅仅只有视图集继承Viewset或者GenericViewset之后,才具备方法名与action进行一一对应的功能 

2.3 重写视图类中的自定义action方法

from .serializers import ProjectNameSerializer@action(methods=['GET', 'POST'], detail=False)def names(self, request, *args, **kwargs):qs = self.get_queryset()# lst = []# for obj in qs:#     dict = {#         'id': obj.id,#         'name': obj.name,#     }#     lst.append(dict)# return Response(lst, content_type='application/json')serializer_obj = ProjectNameSerializer(instance=qs, many=True)return Response(serializer_obj.data, status=status.HTTP_200_OK)

 2.4 将ProjectNameSerializer抽离出来,并且重写get_serializer_class方法

  • 如果当前类视图中,使用了多个不同的序列化器类,那么可以将get_serializer_class重写
  • 继承视图集类之后,会提供action属性,指定当前请求的action方法名称
  • 可以根据不同的action去选择不同的序列化器类(不同的查询集)
    @action(methods=['GET', 'POST'], detail=False)def names(self, request, *args, **kwargs):qs = self.get_queryset()serializer_obj=self.get_serializer(instance=qs, many=True)return Response(serializer_obj.data, status=status.HTTP_200_OK)def get_serializer_class(self):if self.action=='names':return ProjectNameSerializerreturn self.serializer_class

 如果请求的是/projects/names/,使用的是自定义的序列化器类进行数据输出

 如果请求的是其他路由路径,能够使用全局指定的序列化器类(serializer_class=ProjectModelSerializer)正常处理数据,进行序列化输出

  •  可以使用action装饰器,指定自定义action方法(使用路由器时,会自动生成路由条目)
  • 如果不指定methods,那么当前action只支持GET方法请求
  • 可以指定当前action支持多个请求方法,需要将请求方法大写添加至列表中
  • detail指定当前action是否为详情视图
  • url_path指定url的路径字符串
  • url_name指定url路径的名称
  • 如果不指定url_path和url_name,默认为action方法名称

 注册路由

在路由表中导入routers

from rest_framework import routersrouter = routers.SimpleRouter()
# 注册路由
router.register(r'projects', views.ProjectsViewSet)urlpatterns = router.urls
​

 注册路由:

  • 仅仅只有视图集才支持定义路由器功能
  • register方法可以注册路由条目
  • 第一个参数为路由条目的前缀,往往需要添加r'子应用名'
  • 第二个参数为视图集对象,无需调用as_view({})
  •  可以定义DefaultRouter对象,相比SimpleRouter路由对象,会自动添加一个根路由(指定当前项目的入口地址)
    • router = routers.DefaultRouter()

 

如果没有指定url_path和url_name,则通过路由名称去获取URL路径

 如果在action里指定了url_path和url_name,则url_path指定url的路径字符串,url_name指定url路径的名称

@action(methods=['GET', 'POST'], detail=False,url_path='na', url_name='an')
def names(self, request, *args, **kwargs):qs = self.get_queryset()

 

 有时候,有些路由我们不想通过路由器生成,需要在urlpatterns里生成

方式一:可以附加router.urls到现有视图的列表.

from rest_framework import routersrouter = routers.SimpleRouter()
# 注册路由
router.register(r'projects', views.ProjectsViewSet)
urlpatterns = []
urlpatterns += router.urls

方式二:或者可以使用 Django 的include函数,就像这样

from rest_framework import routersrouter = routers.SimpleRouter()
# 注册路由
router.register(r'projects', views.ProjectsViewSet)
urlpatterns = [path('', include(router.urls))
]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/27158.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

4、深入理解ribbon

一、负载均衡的两种方式 服务器端负载均衡 传统的方式前端发送请求会到我们的的nginx上去,nginx作为反向代理,然后路由给后端的服务器,由于负载均衡算法是nginx提供的,而nginx是部署到服务器端的,所以这种方式又被称为…

ETLBox for .Net Crack

ETLBox for .Net Crack 为设计的轻量级ETL(提取转换负载)工具箱和数据集成库。NET。 ETL是现代商业智能应用程序的基础,是将分析与之前的所有其他组件分离的唯一方法。ETL是提取-加载、转换和转换的缩写,描述了一个由三个步骤组成的过程: 提取…

【Unity面试篇】Unity 面试题总结甄选 |热更新与Lua语言 | ❤️持续更新❤️

前言 关于Unity面试题相关的所有知识点:🐱‍🏍2023年Unity面试题大全,共十万字面试题总结【收藏一篇足够面试,持续更新】为了方便大家可以重点复习某个模块,所以将各方面的知识点进行了拆分并更新整理了新…

javascript中过滤二维对象数组重复的字段并只保留唯一值(array.filter与Array.from)

javascript中过滤二维对象数组重复的字段并只保留唯一值 1.Array.filter过滤array.filter()方法 2.Array.from过滤Array.from方法 1.Array.filter过滤 在JavaScript中,你可以使用Array.filter()和Set数据结构来过滤二维对象数组中重复的字段,只保留唯一…

Java日期类

日期类 第一代日期类: 1、Date:精确到毫秒,代表特定的瞬间 2、SimpleDateFormat: **格式化和解析日期的具体类,**它允许进行:格式化(日期 → 文本) 解析(文本 → 日期) 和 规范化。 3、常用的使用方法…

SpringBoot源码分析(6)--SpringBootExceptionReporter/异常报告器

文章目录 一、前言二、异常报告器介绍2.1、作用2.2、接口定义2.3、FailureAnalyzer错误分析器2.4、FailureAnalysisReporter错误报告器 三 、SpringBootExceptionReporter源码分析四、shutdownHook介绍4.1、背景4.2、什么是Shutdown Hook4.3、什么时候会调用Shutdown Hook4.4、…

NUXT3学习笔记2

1、配置Ant design Vue (两个安装方式随便选一种,yarn会安装的更快) npm i ant-design-vue --save yarn add ant-design-vue 2、使⽤的 Vite,你可以使⽤ unplugin-vue-components 来进⾏按需加载。 yarn add unplugin-vue-components --save 在nuxt.…

第一阶段-第十一章 Python基础的综合案例(数据可视化-地图可视化)

目录 一、基础地图使用  1.学习目标  2.视觉映射器  3.本节的演示二、疫情地图-国内疫情地图  1.案例效果  2.函数的语法  3.本节的代码演示三、疫情地图-省级疫情地图  1.案例效果  2.本节的代码演示 说明:该文章是学习 黑马程序员在B站上分享的视…

【c++修行之路】IO流架构及使用

文章目录 前言输入输出库文件读写序列化与反序列化结语 前言 大家好久不见,今天一起来学习c中的IO流。 输入输出库 这两张架构图略显复杂,这里给出一张比较清楚的IO流架构图: 也就是说,我们平时使用的诸如cin、cout、cerr、cl…

python selenium.webdriver 爬取政策文件

文章目录 获取文章链接批量爬取政策文件应用selenium爬取文件信息数据处理导出为excel 获取文章链接 获取中央人民政府网站链接,进入国务院政策文件库,分为国务院文件和部门文件(发改委、工信部、交通运输部、市场监督局、商务部等&#xff…

QT实现按钮开关Form窗体的效果

实现效果叙述如下: MainWindow中的按钮实现Form窗体的开关,Form窗体的关闭按钮禁用掉,只允许使用窗体按钮进行,且关闭MainWindow按钮时Form窗体随之关闭。 注意: 要想实现关闭MainWindow按钮时Form窗体随之关闭&#x…

k8s之Pod容器资源限制

目录 一、Pod 容器的资源限制二、CPU 资源单位三、内存资源单位四、为本地临时性存储设置请求和限制五、总结 一、Pod 容器的资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小,以及其他类型的资源。 当为…