Django中@transaction.non_atomic_requests在ViewSet方法中失效问题
解决DRF ViewSet中@transaction.non_atomic_requests装饰器无效的问题
我懂你遇到的困扰——全局开启ATOMIC_REQUESTS=True后,直接给ViewSet的create方法加@transaction.non_atomic_requests装饰器没起作用,没法在请求里安全地关闭和重新连接数据库来优化性能。这其实是因为类视图的方法装饰逻辑和普通函数视图不一样,我给你两个靠谱的解决方案:
方案一:装饰整个ViewSet类
如果这个视图里的所有请求都不需要原子事务,直接把装饰器加在类上就行,这样能覆盖全局的ATOMIC_REQUESTS设置:
from django.db import transaction from rest_framework import viewsets @transaction.non_atomic_requests class YourTargetViewSet(viewsets.ModelViewSet): queryset = YourModel.objects.all() serializer_class = YourModelSerializer def create(self, *args, **kwargs): # 这里可以放心调用db.connection.close()和connect() # 编写你的业务逻辑 return super().create(*args, **kwargs)
方案二:只装饰特定方法(比如create)
如果你只想让create方法跳过原子事务,需要用method_decorator把函数装饰器适配成类方法能用的形式:
from django.db import transaction from django.utils.decorators import method_decorator from rest_framework import viewsets class YourTargetViewSet(viewsets.ModelViewSet): queryset = YourModel.objects.all() serializer_class = YourModelSerializer @method_decorator(transaction.non_atomic_requests) def create(self, *args, **kwargs): # 执行数据库连接操作和业务逻辑 return super().create(*args, **kwargs)
为什么直接装饰方法没用?
原因很简单:@transaction.non_atomic_requests是为函数视图设计的装饰器,而ViewSet里的方法是类的实例方法。Django的事务中间件是在视图的dispatch方法层面处理自动事务的,直接装饰create方法无法让中间件感知到要跳过原子事务包裹。用method_decorator或者直接装饰类,才能让装饰器正确作用于整个请求处理流程。
验证是否生效的小技巧
你可以在create方法里加一行代码打印自动提交状态,来确认非原子事务是否生效:
def create(self, *args, **kwargs): print(transaction.get_autocommit()) # 如果输出True,说明非原子事务已经生效 # 你的业务代码
内容的提问来源于stack exchange,提问作者hannu40k
相关产品推荐
相关产品推荐

