drf框架之自定义action(代码片段)

xiaogongjin xiaogongjin     2022-12-07     478

关键词:

一、自定义action

  • 使用action装饰器
  • methods
    • 支持的请求方式,为一个列表,默认为[‘get‘]
  • detail
    • 必传参数,
    • 要处理的是否是详情资源对象(即是否通过url路径获取主键)
    • True表示需要传递主键id,使用通过URL获取的主键对应的数据对象
    • False表示不需要传递主键id,不使用URL获取主键
  • url_path
    • 指定url部分,默认为action名称
  • url_name
    • 指定url的名称,默认为action名称

二、action源码

def action(methods=None, detail=None, url_path=None, url_name=None, **kwargs):
    """
    Mark a ViewSet method as a routable action.

    `@action`-decorated functions will be endowed with a `mapping` property,
    a `MethodMapper` that can be used to add additional method-based behaviors
    on the routed action.

    :param methods: A list of HTTP method names this action responds to.
                    Defaults to GET only.
    :param detail: Required. Determines whether this action applies to
                   instance/detail requests or collection/list requests.
    :param url_path: Define the URL segment for this action. Defaults to the
                     name of the method decorated.
    :param url_name: Define the internal (`reverse`) URL name for this action.
                     Defaults to the name of the method decorated with underscores
                     replaced with dashes.
    :param kwargs: Additional properties to set on the view.  This can be used
                   to override viewset-level *_classes settings, equivalent to
                   how the `@renderer_classes` etc. decorators work for function-
                   based API views.
    """
    methods = [get] if (methods is None) else methods
    methods = [method.lower() for method in methods]

    assert detail is not None, (
        "@action() missing required argument: ‘detail‘"
    )

    # name and suffix are mutually exclusive
    if name in kwargs and suffix in kwargs:
        raise TypeError("`name` and `suffix` are mutually exclusive arguments.")

    def decorator(func):
        func.mapping = MethodMapper(func, methods)

        func.detail = detail
        func.url_path = url_path if url_path else func.__name__
        func.url_name = url_name if url_name else func.__name__.replace(_, -)

        # These kwargs will end up being passed to `ViewSet.as_view()` within
        # the router, which eventually delegates to Django‘s CBV `View`,
        # which assigns them as instance attributes for each request.
        func.kwargs = kwargs

        # Set descriptive arguments for viewsets
        if name not in kwargs and suffix not in kwargs:
            func.kwargs[name] = pretty_name(func.__name__)
        func.kwargs[description] = func.__doc__ or None

        return func
    return decorator

三、使用方法

 1.引入action

from rest_framework.decorators import action

2.定义一个序列化器类

from rest_framework import serializers
from .models import Projects


class ProjectsNamesModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Projects
        fields = (id, name)

3.自定义action方法

使用装饰器@action(),传入methods和detail等参数值

@action(methods=[get], detail=False)
    def names(self, request):
        qs = self.filter_queryset(self.get_queryset())
        page = self.paginate_queryset(qs)
        if page:
            serializer_obj = self.get_serializer(instance=page, many=True)
            return Response(serializer_obj.data)
        serializer_obj = self.get_serializer(instance=qs, many=True)
        return Response(serializer_obj.data)

4.重写get_serializer_class方法

使用self.action可以获取到传入的action,因此可以使用if判断来满足特定条件下返回不同的序列化器类

    def get_serializer_class(self):
        if self.action == names:
            return ProjectsNamesModelSerializer
        else:
            return self.serializer_class

5.配置路由信息

from django.contrib import admin
from django.urls import path
from projects.views import ProjectsPageSet


urlpatterns = [
    path(admin/, admin.site.urls)
    path(projects/names/, ProjectsPageSet.as_view(
        get: names
    ))
]

验证结果:

技术图片

四、从表关联

需求:指定获取某个项目下对应的从表的id和name?

1.定义序列化器类

from rest_framework import serializers
from .models import Projects
from interfaces.models import Interfaces


class InterfacesNamesModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Interfaces
        fields = (id, name)


class InterfacesByProjectIdModelSerializer(serializers.ModelSerializer):
    interfaces = InterfacesNamesModelSerializer(many=True, read_only=True, label=从表id, help_text=从表id)

    class Meta:
        model = Projects
        fields = (id, interfaces)

2.自定义action方法

@action(methods=[get], detail=True)
    def interfaces(self, request, *args, **kwargs):
        qs = self.get_object()
        serializer_obj = self.get_serializer(instance=qs)
        return Response(serializer_obj.data)

3.重写get_serializer_class方法

    def get_serializer_class(self):
        if self.action == interfaces:
            return InterfacesByProjectIdModelSerializer
        else:
            return self.serializer_class

验证结果:

技术图片

drf项目之自定义分页器(代码片段)

在项目中,我们多需要自定义分页器。代码实现fromrest_framework.paginationimportPageNumberPaginationfromrest_framework.responseimportResponseclassPageNum(PageNumberPagination):page_size=5#后端指定每页显示数量page_size_query_param=‘pag 查看详情

drf框架之路由routers(代码片段)

...到路由表中urlpatterns+=router.urls当我们定义好Routers后,DRF框架会使用Routers为我们自动创建好路由信息,但是自定义的action并不会自动创建路由信息。2.为自定义action自动创建路由信息在视图集中,如果想要让Router自动帮助我们为... 查看详情

使用drf视图集时自定义action方法(代码片段)

在我们用DRF视图集完成了查找全部部门,创建一个新的部门,查找一个部门,修改一个部门,删除一个部门的功能后,views.py的代码是这样子的:classDepartmentViewSet(ModelViewSet):queryset=Department.objects.all()serializer_class=DepartmentSerializer... 查看详情

mybatis进阶之自定义mybatis框架(代码片段)

MyBatis进阶之自定义MyBatis框架1.自定义MyBatis框架流程分析2.自定义框架原理介绍3.准备工作:1)创建maven工程Groupid:com.itheimaArtifactId:custom-mybatisPacking:jar2)添加pom依赖:<dependency><groupId>mysql</groupId&g 查看详情

et框架之自写模块smarttimermodule(代码片段)

1.代码结构图2.SmartTimer模块Entity:1usingSystem;23namespaceETModel45[ObjectSystem]6publicclassSmartTimerAwakeSystem:AwakeSystem<SmartTimer,float,uint,Action>78publicoverridevoidAwake(SmartTimerself,f 查看详情

mapreduce之自定义inputformat(代码片段)

在企业开发中,Hadoop框架自带的InputFormat类型不能满足所有应用场景,需要自定义InputFormat来解决实际问题。自定义InputFormat步骤如下:(1)自定义一个类继承FilelnputFormat。(2)自定义一个类继承RecordReader,实现一次读取一个完... 查看详情

wpf编程之自定义button控件样式(代码片段)

  自.NETFramework3.0以后,WPF编程框架可使开发人员开发出更加令人耳目一新的桌面应用程序。它使开发工作更加方便快捷,它将设计人员和编程人员的工作分离开来。至于WPF的背景历史、框架特点、框架结构这里就不再赘述。... 查看详情

flask框架从入门到精通之自定义response(代码片段)

知识点:1、自定义响应信息2、返回Json一、概况我们都知道当浏览器发起一个请求时,服务器会给一个响应。这个响应包含了返回的内容类型,状态码,服务器版本等一些。如下图:如果我们不进行修改这里... 查看详情

drf的@action装饰器(代码片段)

#转自:http://www.cnblogs.com/zhzhlong/p/9325180.html视图集中附加action的声明fromrest_framework.decoratorsimportaction#追加action:返回书记的倒叙地0个书籍的信息@action(methods=[‘get‘],detail=False)deflatest(self,request):"""#追加ac 查看详情

drf框架路由组件(代码片段)

视图组件涉及的路由补充:  fromrest_framework.viewsetsimportViewSetMixin  对路由进行了重新的分发,重写了as_view()方法,重新封装了请求方法fromrest_framework.viewsetsimportViewSetMixinclassViewSetMixin(object):"""Thisisthemagic.Overrides`.as_view()`sothati... 查看详情

django快速开发实践:drf框架和xadmin配置指北(代码片段)

步骤既然是快速开发,那废话不多说,直接说步骤:安装Djagno安装DjangoRestFramework定义models定义Restframework的serializers定义Restframework的viewsets配置Restframework的router配置管理后台admin根据需要写template和对应的view经过这些步骤就能得... 查看详情

drf框架认证组件(代码片段)

DRF框架的认证组件核心代码:    self.perform_authentication(request) 框架自带模块:   fromrest_frameworkimportauthentication 认证组件的返回值:request.user自定义的认证组件的钩子方法authenticator.authenticate(self);返... 查看详情

wpf之自定义滚动条(代码片段)

原文:wpf之自定义滚动条首先我们添加一个带滚动条的textbox控件:<ScrollViewerHeight="130"Width="620"VerticalScrollBarVisibility="Auto"Style="StaticResourcefor_scrollviewer"><TextBlockxml:space="preserve"Name="FtpServe 查看详情

drf框架serializer之modelserializer(代码片段)

...性,因此会选择一种更为简洁的序列化器类来帮我们优化框架代码,简化序列化器类中字段的创建常规序列化器类示例:fromrest_frameworkimportserializersfromrest_frameworkimpo 查看详情

jvm进阶之自定义类加载器(代码片段)

...加载器1.作用2.场景3.注意4.实现1.作用隔离加载类在某些框架内进行中间件与应用的模块隔离,把类加载到不同的环境。修改类加载的方式类的加载模型并非强制的,应该根据实际情况在某个时间点按需进行动态加载。扩... 查看详情

jvm进阶之自定义类加载器(代码片段)

...加载器1.作用2.场景3.注意4.实现1.作用隔离加载类在某些框架内进行中间件与应用的模块隔离,把类加载到不同的环境。修改类加载的方式类的加载模型并非强制的,应该根据实际情况在某个时间点按需进行动态加载。扩... 查看详情

drf05(代码片段)

目录Response封装深度查询子depth深度查询之自定义@property方法delete请求实现单删群删post请求实现单增群增ListSerializerput请求实现整体单改和整体群改patch请求实现局部单改和局部整改Response封装经过前面的学习我们可以发现,我们每... 查看详情

springcloud系列之自定义gatewayfilterfactory(代码片段)

SpringCloud系列之自定义GatewayFilterFactory学习目的:知道创建一个网关sample知道网关的基本配置知道自定义GatewayFilterFactory类环境准备:JDK1.8SpringBoot2.2.3SpringCloud(Hoxton.SR7)Maven3.2+开发工具IntelliJIDEAsmartGit新增SpringBootInitializer项目:N 查看详情