You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现函数与装饰器间的变量传递?animal与model_data交互咨询

针对你遇到的装饰器和原函数之间变量互传的问题,我给你两种需求对应的具体实现方案,结合你的Django视图场景来拆解:

需求1:把装饰器的model_data传递给原函数

这种场景比较常见,因为装饰器通常是在视图函数执行前预处理数据,我们可以通过两种友好的方式传递:

方式1:挂载到request对象上(推荐,不改变视图签名)

修改你的parse_model_data装饰器,把生成的model_data挂载到request的自定义属性上:

def parse_model_data(func):
    def wrapper(request, *args, **kwargs):
        # 这里是你生成model_data的逻辑,比如解析请求、查询数据库等
        model_data = {"some_key": "processed_value"}
        
        # 把model_data挂载到request对象
        request.model_data = model_data
        
        # 执行原视图函数
        return func(request, *args, **kwargs)
    return wrapper

然后原视图函数直接通过request获取即可:

@csrf_exempt 
@require_http_methods(["GET", "PUT", "DELETE"]) 
@parse_model_data 
def base_animal(request, model_id):
    try:
        animal = Animal.objects.get(id=model_id)
        # 直接使用装饰器传递过来的model_data
        print("从装饰器拿到的model_data:", request.model_data)
        # ... 你的业务逻辑
        return JsonResponse({"status": "success", "animal": animal.name})
    except Animal.DoesNotExist:
        return JsonResponse({"error": "Animal not found"}, status=404)

方式2:作为额外参数传递

如果不喜欢挂载到request,也可以给原视图函数加一个参数接收:

def parse_model_data(func):
    def wrapper(request, *args, **kwargs):
        model_data = {"some_key": "processed_value"}
        # 把model_data作为额外参数传给原函数
        return func(request, model_data, *args, **kwargs)
    return wrapper

原视图函数修改参数列表:

@csrf_exempt 
@require_http_methods(["GET", "PUT", "DELETE"]) 
@parse_model_data 
def base_animal(request, model_data, model_id):  # 注意参数顺序
    try:
        animal = Animal.objects.get(id=model_id)
        print("从装饰器拿到的model_data:", model_data)
        # ... 业务逻辑
        return JsonResponse({"status": "success"})
    except Animal.DoesNotExist:
        return JsonResponse({"error": "Animal not found"}, status=404)
需求2:把原函数的animal传递给装饰器

这种情况要注意:装饰器默认是在原函数执行前运行的,而animal是原函数内部生成的变量,所以必须等原函数执行到生成animal的步骤后,再让装饰器获取它。这里给你一种简单直接的实现方式:

修改装饰器,让它捕获原函数返回的包含animal和响应的元组,处理完animal后再返回响应:

def parse_model_data(func):
    def wrapper(request, *args, **kwargs):
        # 执行原函数,拿到animal和响应对象
        animal, response = func(request, *args, **kwargs)
        
        # 在这里就可以使用原函数的animal变量了
        if animal:
            print("装饰器拿到的animal:", animal.name)
            # 比如做一些后续处理:更新日志、同步数据等
        # 最后返回响应
        return response
    return wrapper

然后修改原视图函数,返回animal和响应的元组:

@csrf_exempt 
@require_http_methods(["GET", "PUT", "DELETE"]) 
@parse_model_data 
def base_animal(request, model_id):
    try:
        animal = Animal.objects.get(id=model_id)
        # ... 你的业务逻辑处理
        response = JsonResponse({"status": "success", "animal": animal.name})
        # 返回animal和响应的元组,让装饰器捕获
        return animal, response
    except Animal.DoesNotExist:
        # 异常情况返回None和错误响应
        return None, JsonResponse({"error": "Animal not found"}, status=404)

如果不想修改原函数的返回值结构,也可以用闭包或者类装饰器来存储状态,但上面的方式是最直观、最适合Django视图场景的。

内容的提问来源于stack exchange,提问作者user1250991

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:28:01