Django中为api自定义一些装饰器:如参数校验等

在Django中使用了rest_framework时,一般我们会定义ModelSerializer来校验request.data中参数是否存在和参数类型。

但当我们只是想简单校验一些api的url上是否存在某些参数时,该怎么办?当然我们也可以通过定义Serializer来实现,但很麻烦。

我们可以自定义请求参数验证装饰器来实现。类似如下(代码不是完整的,只是示例):

python 复制代码
from functools import wraps

from django.utils import six
from django.utils.decorators import available_attrs


def request_params_required(param_names, raise_exception=False):
    """
    验证request的URL中必须的参数
    :param param_names:
    :param raise_exception:
    :return:
    """
    def decorator(view_func):
        @wraps(view_func, assigned=available_attrs(view_func))
        def _wrapped_view(request, *args, **kwargs):
            request_params = request.GET
            if isinstance(param_names, six.string_types):
                params = (param_names,)
            else:
                params = param_names
            for param in params:
                if param not in request_params:
                    return json_response_request_params_required(param)
            return view_func(request, *args, **kwargs)

        return _wrapped_view

    return decorator

以上代码中使用@wraps(view_func, assigned=available_attrs(view_func))的目的是保留原始函数的身份信息

在需要验证url参数的api上就可以使用上面的请求参数验证装饰器(代码不是完整的,只是示例:

python 复制代码
@api_view(['GET'])
@request_params_required('redirect_uri')
def gitlab_login_oauth_uri(request):
    redirect_uri = request.GET.get('redirect_uri')
    if not redirect_uri:
        return api_request_params_required("redirect_uri")
    client = GitlabOauthClient()
    oauth_url = client.get_oauth_url(redirect_uri)
    return api_success({'oauth_url': oauth_url})


@api_view(['GET'])
@request_params_required(['page', 'page_size'])
def all_report_list(request):
    data = []
    """
    省略业务逻辑
    """
    return api_success(data)

上面的装饰器,需要传递格外参数,所以必须是三层。不需要传递参数的装饰器两层就够了。如下一个跳过CSRF验证的装饰器。

python 复制代码
def csrf_ignore(view_func):
    """
    Skips the CSRF checks by setting the 'csrf_processing_done' to true.
    """

    def wrapped_view(request, *args, **kwargs):
        request.csrf_processing_done = True
        return view_func(*args, **kwargs)

    return wraps(view_func, assigned=available_attrs(view_func))(wrapped_view)
相关推荐
啥都学点的程序员18 分钟前
python实现的websocket日志类
后端·python
ZeroNews内网穿透1 小时前
ZeroNews内网穿透安全策略深度解析:构建企业级安全连接体系
java·运维·服务器·网络·python·安全·php
仪器科学与传感技术博士1 小时前
python:如何调节机器学习算法的鲁棒性,以支持向量机SVM为例,让伙伴们看的更明白
python·算法·机器学习
安冬的码畜日常2 小时前
【AI 加持下的 Python 编程实战 2_13】第九章:繁琐任务的自动化(中)——自动批量合并 PDF 文档
人工智能·python·自动化·ai编程·ai辅助编程
@十八子德月生3 小时前
第三阶段—8天Python从入门到精通【itheima】-143节(pyspark实战——数据计算——flatmap方法)
大数据·开发语言·python·数据分析·pyspark·好好学习,天天向上·question answer
孫治AllenSun3 小时前
【Java】使用模板方法模式设计EasyExcel批量导入导出
java·python·模板方法模式
爱编码的程序员3 小时前
python 处理json、excel、然后将内容转化为DSL语句,适用于数据处理(实用版)
人工智能·python·ai·json·excel·数据处理·dsl
ashcn20013 小时前
vim 组件 使用pysocket进行sock连接
python·vim·excel
王国强20093 小时前
Pydantic 深度指南:Python 类型安全与数据建模的现代解决方案
python
天宁4 小时前
TCP粘包问题解决方案
python