【问题标题】:Django decorator @transaction.non_atomic_requests not working in a ViewSet methodDjango 装饰器@transaction.non_atomic_requests 在 ViewSet 方法中不起作用
【发布时间】:2018-04-18 15:04:49
【问题描述】:

我最近遇到需要在我的一个视图中禁用事务请求,以便能够在请求期间调用db.connection.close()connect() 以提高性能。

我有一个 DRF ViewSet,并使用以下非常简单的视图来验证 non_atomic_requests 装饰器似乎没有效果。 ATOMIC_REQUESTS=Truesettings.pyDEBUG=False 中启用。

from django.db import transaction    

@transaction.non_atomic_requests
def create(self, *args, **kwargs):
    m = MyModel(stuff="hello")
    m.save()
    raise Exception('exception! row should still be saved though')
    return Response()

调用视图后,我打开 Django shell,并验证数据库中的行数没有增加,即使它应该增加。在m.save() 行之后请求停止执行期间还打开一个调试器,我可以在 Django shell 中观察到新行尚不可见。

如果我在settings.py 中设置ATOMIC_REQUESTS=False,代码将按预期工作,并且数据库中的行数增加一,即使在从视图返回之前引发错误。

ATOMIC_REQUESTS=False 时,使用@transaction.atomic 装饰器确实可以按预期工作。因此,作为一种解决方法,我可以使用它将所有其他视图设置为原子...

我目前认为这是框架中的一个错误。谁能验证我的发现,或者指出我是否误解了这个装饰器的功能?

我正在使用 Python 3.6、Django 2.0 和 DRF 3.7.7。

【问题讨论】:

  • 由于之前的加薪,返回线永远不会到达

标签: python django transactions django-rest-framework


【解决方案1】:

As documented, non_atomic_requests 仅适用于视图本身。

在您的情况下,create 是一种视图集方法,它不是视图本身。在 Django 中使用基于常规类的视图,您需要使用 method_decorator 包装 dispatch 方法。

@method_decorator(transaction.non_atomic_requests, name='dispatch') 
class MyViewSet(ViewSet):
    ...

    def create(self, *args, **kwargs):
        ...

我对其余框架的内部结构不够熟悉,无法说明这是否可行。请注意,它将禁用对视图集处理的所有视图的原子请求,而不仅仅是create 方法。

non_atomic_requests 方法有这个限制,因为 Django 请求处理程序必须在运行之前检查视图,以便知道是否在事务中运行它。 transaction.atomic 装饰器没有相同的要求 - Django 可以简单地在事务进入原子函数或块时立即启动它。

【讨论】:

  • 有没有人确认这适用于 Django Rest Framework ViewSets?它对我不起作用。
  • @JoshuaSwain 在我看来它应该可以工作,因为视图集从调度方法here 复制属性。我还没有尝试过确认它确实有效。
猜你喜欢
  • 2020-11-09
  • 2015-09-03
  • 1970-01-01
  • 1970-01-01
  • 2015-03-17
  • 2019-04-12
  • 2019-04-23
  • 2017-09-28
  • 1970-01-01
相关资源
最近更新 更多