drf开发常用工具函数总结(给请求封装通用参数、打印内置属性/方法、动态构建查找条件、yaml读取真正的环境变量、异常处理之自定义异常类和捕捉系统异常)

本文主要是介绍drf开发常用工具函数总结(给请求封装通用参数、打印内置属性/方法、动态构建查找条件、yaml读取真正的环境变量、异常处理之自定义异常类和捕捉系统异常),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

给请求封装通用参数

使用中间件

中间件可以在请求进入视图之前或响应返回给客户端之前执行代码。你可以创建一个自定义中间件来添加通用参数。

class CommonParamsMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):request.common_params = {'param1': 'value1','param2': 'value2',}response = self.get_response(request)return response

然后在你的settings.py中添加这个中间件:

MIDDLEWARE = [# ..'path.to.your.middleware.CommonParamsMiddleware',
]

在你的视图中,你可以通过request.common_params来访问这些参数。

使用自定义视图基类

如果你想要在视图层面添加通用参数,你可以创建一个自定义的视图基类,并在其他视图中继承它。

# views.py
from rest_framework.views import APIViewclass CommonParamsAPIView(APIView):def initialize_request(self, request, *args, **kwargs):request = super().initialize_request(request, *args, **kwargs)# 在这里添加你的通用参数request.common_params = {'param1': 'value1','param2': 'value2',}return request# 然后在你的其他视图中继承这个基类
class MyView(CommonParamsAPIView):def get(self, request, *args, **kwargs):# 使用通用参数common_params = request.common_params# ...

这样,任何继承CommonParamsAPIView的视图都会自动获得这些通用参数。

使用视图装饰器

如果你不想创建一个新的基类,你也可以使用装饰器来修改视图的行为。

# decorators.py
from functools import wrapsdef add_common_params(view_func):@wraps(view_func)def _decorated(view_instance, request, *args, **kwargs):# 在这里添加你的通用参数request.common_params = {'param1': 'value1','param2': 'value2',}return view_func(view_instance, request, *args, **kwargs)return _decorated# 在你的视图中使用装饰器
from rest_framework.decorators import api_view
from .decorators import add_common_params@api_view(['GET'])
@add_common_params
def my_view(request):# 使用通用参数common_params = request.common_params# ...

选择哪种方法取决于你的具体需求和偏好。中间件适用于全局的请求处理,自定义视图基类和装饰器则提供了更细粒度的控制。

打印所有内置属性/方法

def log_request(self, request):for attr in dir(request):if not attr.startswith('_'):# 检查属性是否存在,避免访问已经被移除的属性if hasattr(request, attr):try:value = getattr(request, attr, None)if not callable(value):print(f"{attr} : {value}")except Exception as e:print(f"Error accessing {attr}: {e}")

callable是一个内置函数,它用来检查一个对象是否是“可调用的”。一个对象如果是可调用的,意味着你可以像函数一样使用它,即可以在后面加上括号和参数来调用它。函数、方法、类以及实现了__call__方法的实例都是可调用的。

动态构建查找条件

def query_some(scope_type, scope_value):# 构建查询参数,其中 scope_type 是一个变量,它的值对应于模型中的字段名filter_kwargs = {scope_type: scope_value}objs = Project.objects.filter(**filter_kwargs).first()if not objs:return os.get("DEFAULT_RESULT")return objs.some_id

从yaml中读取真正的环境变量

# 必须参数
name: "MyNewSpace" 
platform_url: os.getenv("XXX")  #
app_code: os.getenv("YYY")# 非必需参数
desc: "Description of the new space."
def handle_env_var(value):# 尝试匹配 os.getenv("...") 格式并从环境变量中拿取真正的值if isinstance(value, str):match = re.match(r"os\.getenv\(['\"](.*?)['\"]\)", value)if match:return os.getenv(match.group(1))return valueelif isinstance(value, dict):for key, v in value.items():value[key] = handle_env_var(v)return valueelif isinstance(value, list):return [handle_env_var(v) for v in value]else:return value

动态构造序列化器内容:

class TASK_ID_KEY(Enum):TASK_ID = "task_tag"

class DemoQuerySerializer(serializers.Serializer):category = serializers.CharField(help_text="API对应的分类", max_length=255, default="test")# 动态添加字段def __init__(self, *args, **kwargs):super(DemoQuerySerializer, self).__init__(*args, **kwargs)self.fields[TASK_ID_KEY.TASK_ID.value] = serializers.CharField(help_text="task_tag_key", max_length=64)

异常处理

统一返回三段式处理函数

class ThirdPartResponse(Response):def __init__(self,result=True,message="",data=None,extra_data=None,status_code=status.HTTP_200_OK,code=None,):if message:message = "Error code: {}, {}".format(code, message)logger.error(message)standardized_data = {"result": result,"message": message,"data": data,}# 如果传入了extra_data,并且它是一个字典,则将其合并到输出字典中if extra_data and isinstance(extra_data, dict):standardized_data.update(extra_data)super().__init__(standardized_data, status_code)

自定义异常类

from rest_framework import statusclass TokenException(Exception):status_code = status.HTTP_400_BAD_REQUESTcode = 1100error = ""def __init__(self, error):self.error = errorclass TokenAPIError(TokenException):code = 1101error = "get access_token from apigw failed"def __init__(self, error):super().__init__(error)class TokenNotExist(TokenException):code = 1102error = "access_token does not exist in db"def __init__(self, error):super().__init__(error)class APIException(Exception):status_code = status.HTTP_200_OKcode = 1200error = ""def __init__(self, error):self.error = errorclass ThirdPartException(APIException):code = 1201error = "第三方请求错误"def __init__(self, error):super().__init__(error)

抛出和捕捉自定义异常

if not response["result"]:  msg = "原样返回上游平台响应:{}".format(str(response))  logger.error(msg)  raise ThirdPartyException(error=msg)
except IpHostFormatException as e:  return ThreePartResponse(status_code=e.status_code, message=e.error, code=e.code)  

捕捉系统异常

except Exception as e:  msg = "reformat_global_vars error: {}".format(str(e))  logger.error(msg)  return ThreePartResponse(message=msg)

正常返回三段式

return ThreePartResponse(data=serializer.data)

补充返回非三段式

return ThreePartResponse(data=data, extra_data=task_id_dict)

这篇关于drf开发常用工具函数总结(给请求封装通用参数、打印内置属性/方法、动态构建查找条件、yaml读取真正的环境变量、异常处理之自定义异常类和捕捉系统异常)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1067610

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表