在django项目中使用装饰器管理路由

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
可观测链路 OpenTelemetry 版,每月50GB免费额度
可观测监控 Prometheus 版,每月50GB免费额度
简介: 【6月更文挑战第12天】本文介绍了Python装饰器在API管理中的应用,包括用于延迟计算、缓存和转换函数的装饰器。实践中,以Django Rest Framework为例,演示了如何使用装饰器定义GET、POST、PUT和DELETE请求的视

简介

本文对比了不同框架中装饰器管理路由的方式,并展示了如何使用propertyclassmethodstaticmethod作为方法装饰器。

在路由处理中,查询参数可以通过装饰器设定默认值、可选性及类型转换。

FastAPI允许指定路径和查询参数,以及通过tagsstatus_coderesponse_model装饰器来管理路径操作。

1 装饰器:管理api的请求和提交

在python中,人们经常使用装饰器来为对象增加或修改功能,比如初始化一个类时,某些属性可能需要很长计算时间, 此时,我们在python中可以创建一个装饰器类。只有在实际使用时,才去创建这个类的属性.

或者一个方法装饰器,它在函数周围应用记忆缓存,做为延迟缓存,而不是延迟结果本身。

或者一些通用函数装饰器, 将一个函数转换成一个泛型函数,它可以有不同的行为,其具体行为取决于其第一个参数的类型。

这里简单对比几个框架使用装饰器实现管理路由的方式

2 示例:方法装饰 property,classmethod和staticmethod: 方法装饰器

  • 装饰器 property:

@property是当您想为对象中的属性定义 getter 和 setter 时使用的装饰器。Getter 和 setter 提供了一种在尝试读取或修改对象的属性时添加验证或运行一些额外代码的方法。

这是通过将属性转换为一组函数来完成的:一个函数在您尝试访问该属性时运行,另一个在您尝试更改其值时运行。

  • 装饰器 classmethod:
      @classmethod可以在方法上使用以使其成为类方法:使其获得对类对象的引用,而不是实例(self)。
    

一个简单的例子是创建一个返回类名的函数:

staticmethod: @staticmethod用于将方法转换为静态方法:一种等效于位于类中的函数,独立于任何类或对象属性。使用它完全摆脱了self传递给方法的第一个参数。

3 示例:路由中的查询参数

声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数 如下skip limit都是查询参数

返回json 格式,原始值 为字符串
限制查一个

    http://127.0.0.1:2000/items/?skip=0&limit=1   

限制查10个

    http://127.0.0.1:2000/items/?skip=0&limit=10  

skip: 对应的值为0
limit: 对应的值 10
参数原始值为 字符串,当你为它们声明一个Python类型时,
它们将转换为该类型并针对该类型进行校验

    @app.get("/items/")
    async def read_time(skip: int = 0, limit: int = 10):

        return fake_items_db[skip:skip + limit]

当你为它们声明了python类型,它们将转换为该类型并针对该类型进行校验。
应用于该路径参数的所有相同过程也适用于查询参数。

    编辑器支持
    数据解析
    数据校验
    自动生成文档
  • 装饰器的 默认值

查询参数可以有默认值 skip=0,limit=10 就是默认值。

  • 装饰器的 可选参数

使用设置None声明可选参数。

  • 装饰器的 多个路径参数和 查询参数

注意 如果 q 和 short 没有默认值 那就是必填查询参数,在这个例子中,有2个查询参数:

    user_id: int,  user_id 必须的int类型 路径参数。
    item_id:str    item_id 必须的str 类型 路径参数
    q,一个必须的 没有默认值的str 类型参数。
    short,一个可选的 bool 类型参数。
  • 装饰器的 多个路径参数 和 查询参数

      @app.get("/user/{user_id}/items/{item_id}")  
      async def read_user_check(user_id: int, item_id:str, q: Optional[str], short:bool=False):
    

q 是可选字符串参数 默认为 None。

FastAPI可以分辨 参数 item_id 是路径参数,而q不是,因此q是查询参数。

查询参数类型转换 声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数

short: 是否排序

short=on 就是查询参数,FastAPI可以 识别 on,yes,True,true,1 为 python的True

    > http://127.0.0.1:2000/user/1/items/2?q=ok&short=false
    < response:
        {"item_id":"2","own_id":1,"q":"ok","description":"This is an amazing item that has a long description"}

4 路径管理的方法装饰器

tags 和 status_code 和 response_model

使用 status 快捷常量 HTTP_201_CREATED
使用 tags 为路径操作 添加标签,tag一般由 str组成的 list构成, 可以用于 api 接口分组

response_model 定义返回数据结构模型

    @app.post("/items/create", response_model=Item, status_code=status.HTTP_201_CREATED, tags=["items"])
    async def create_item(item:Item):
        return item

使用:
POST /items/create Create an item

如果 description参数 与接口的docs 都设置了,那么只会显示一个描述 默认为路径中定义的,

路径装饰器还支持高级设置通过参数opeeration_id 设置 要使用的OpenAPO operationId

但是需要确保每个操作路径的 opeeration_id都是唯一的。

剩余部分不会出现在文档中,但是其他工具(比如 Sphinx)可以使用剩余部分。

5 实践:路径管理的方法装饰器

在HTTP中通常使用 GET,POST 获取全部信息,和添加信息

我们可以通过api使用者的post请求体body 携带的 json参数来添加内容, 并通过get来获取内容。

  • 首先,修改视图模块 views

导入管理器api_view,视图管理装饰器,决定请求方式,
并且导入Response和status当有错误请求时的错误码定义,决定api返回的内容。employee/views.py

from rest_framework.decorators import api_view    
from rest_framework.response import Response   
from rest_framework import status         
import rest_framework
@api_view(['GET', 'POST'])
def blog_api_view(request):
    if request.method == "GET":
        serializer = TaskSerializer(EmployeeSign.objects.all(), many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
        serializer = TaskSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  • 然后,修改应用的 路由

添加路由

from .views import blog_api_view
#employee/urls.py 
        ...
        path('blogs_tasks/', blog_api_view, name='blog_api_view'),
        ...
  • PUT,DELETE 更新与删除任务信息

我们有时需要为某一个任务 进行更新或删除操作, 新增如下方法employee/views.py

        @api_view(['GET', 'PUT', 'DELETE'])
        def api_detail_view(request, pk=None):
            try:
                bapi = EmployeeSign.objects.get(pk)
            except:
                return Response(status=status.HTTP_404_NOT_FOUND)
            if request.method == 'GET':
                serializer = TaskSerializer(bapi)
                return Response(serializer.data)
            elif request.method == 'PUT':
                serializer = TaskSerializer(bapi, data=request.data)
                if serializer.is_valid():
                    serializer.save()
                    return Response(serializer.data)
                return Response(bapi.errors, status=status.HTTP_400_BAD_REQUEST)
            elif request.method =='DELETE':
                bapi.delete()
                return Response(status=status.HTTP_204_NO_CONTENT)
  • 更新和删除的url api路由employee/urls.py

      path('blogs_tasks/', blog_api_view, name='blog_api_view'),
      path('blogs_tasks/<int:pk>/', api_detail_view, name='api_detail_view'),
    

6 小结

在flask和FastAPI这类框架中,传递参数给路径操作装饰器,即可轻松地配置路径操作、添加元数据,但是多个方法可能叠加几层装饰器。

可以看到在django的插件框架中,个人认为其使用更加具有灵活性和也更加清晰。

看官们认为如何?

目录
相关文章
|
8天前
|
机器学习/深度学习 人工智能 算法
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
植物病害识别系统。本系统使用Python作为主要编程语言,通过收集水稻常见的四种叶片病害图片('细菌性叶枯病', '稻瘟病', '褐斑病', '稻瘟条纹病毒病')作为后面模型训练用到的数据集。然后使用TensorFlow搭建卷积神经网络算法模型,并进行多轮迭代训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地模型文件。再使用Django搭建Web网页平台操作界面,实现用户上传一张测试图片识别其名称。
55 21
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
|
8天前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
37 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
4天前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
18 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
2天前
|
Linux Python
解决django项目报错很离谱的报错之RuntimeError: populate() isn't reentrant
解决django项目报错很离谱的报错之RuntimeError: populate() isn't reentrant
|
4天前
|
机器学习/深度学习 人工智能 算法
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台。果蔬识别系统,本系统使用Python作为主要开发语言,通过收集了12种常见的水果和蔬菜('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜'),然后基于TensorFlow库搭建CNN卷积神经网络算法模型,然后对数据集进行训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地文件方便后期调用。再使用Django框架搭建Web网页平台操作界面,实现用户上传一张果蔬图片识别其名称。
19 0
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
1月前
|
运维 Devops 测试技术
一个人活成一个团队:python的django项目devops实战
DevOps通过自动化的流程,使得构建、测试、发布软件能够更加地快捷、频繁和可靠。本文通过一个python的django个人博客应用进行了DevOps的实战,通过DevOps拉通开发和运维,通过应用云效的DevOps平台实现自动化“软件交付”的流程,使得构建、测试、发布软件能够更加地快捷、频繁和可靠,提交研发交付效率。作为个人项目也是可以应用devops提高效率。
37 3
|
1月前
|
Python SEO
Django入门到放弃之路由
Django入门到放弃之路由
|
1月前
|
JSON API 数据安全/隐私保护
Django 后端架构开发:JWT 项目实践与Drf版本控制
Django 后端架构开发:JWT 项目实践与Drf版本控制
33 0
|
1月前
|
存储 前端开发 Serverless
中后台前端开发问题之Django项目中接收和处理用户的抽奖请求如何解决
中后台前端开发问题之Django项目中接收和处理用户的抽奖请求如何解决
13 0
|
2月前
|
安全 前端开发 API
震惊!掌握Django/Flask后,我竟然轻松征服了所有Web项目难题!
【7月更文挑战第15天】Python Web开发中,Django以其全面功能见长,如ORM、模板引擎,助你驾驭复杂需求;Flask则以轻量灵活取胜,适合快速迭代。两者结合使用,无论是数据库操作、用户认证还是API开发,都能让你应对Web挑战游刃有余。掌握这两者,Web项目难题变得易如反掌!
65 10