Django REST Framework故意引发错误时的事务错误

Max*_*ant 8 django sqltransaction django-rest-framework

我已经使用Django REST Framework从2.x版本更新了一个项目到最后一个稳定版本(3.1.3).在我的序列化程序中修复了一些已弃用的用法之后,我跑去python manage.py test确保没有任何内容被破坏.

一切正常,除了我测试无效REST请求(我故意)的一些测试.例如:

def test_get_events_of_other_user(self):
    # Assume the setUp log the user1 with self.client 
    # and here, there is some code initializing an 
    # event for user2
    response = self.client.get("/event/123/")
    self.assertEqual(404, response.status_code)
Run Code Online (Sandbox Code Playgroud)

视图集生成一个ORM查询MyEventModel.objects.get(user=request.user, pk=123),这显然会在DRF中引发404异常,因为这里不应该返回任何对象(我知道,它应该是一个符合REST的403 ...).但这提出了一个TransactionManagementError:

Traceback (most recent call last):
  [...]
  File "/my_virtual_env_path/local/lib/python2.7/site-packages/rest_framework/viewsets.py", line 85, in view
    return self.dispatch(request, *args, **kwargs)
  File "/my_virtual_env_path/local/lib/python2.7/site-packages/rest_framework/views.py", line 456, in dispatch
    response = self.handle_exception(exc)
  File "/my_virtual_env_path/local/lib/python2.7/site-packages/rest_framework/views.py", line 421, in handle_exception
    response = exception_handler(exc, context)
  File "/my_virtual_env_path/local/lib/python2.7/site-packages/rest_framework/views.py", line 81, in exception_handler
    set_rollback()
  File "/my_virtual_env_path/local/lib/python2.7/site-packages/rest_framework/compat.py", line 277, in set_rollback
    transaction.set_rollback(True)
  File "/my_virtual_env_path/local/lib/python2.7/site-packages/django/db/transaction.py", line 215, in set_rollback
    return get_connection(using).set_rollback(rollback)
  File "/my_virtual_env_path/local/lib/python2.7/site-packages/django/db/backends/__init__.py", line 372, in set_rollback
    "The rollback flag doesn't work outside of an 'atomic' block.")
TransactionManagementError: The rollback flag doesn't work outside of an 'atomic' block.
Run Code Online (Sandbox Code Playgroud)

看起来我的中间件之一是在视图之后进行一些SQL查询,并且在3.1.3之后命中DRF关闭事务.期望的行为(即获得404 NOT FOUND)适用于3.1.2 ......

有没有人知道如何避免回滚?这是DRF的误解吗?

Pet*_*ain 2

这看起来像是 DRF 中的一个错误,已被修复。正如您在这里看到的,他们更改了代码,以便仅在原子块中时回滚。

由于没有发布更新的版本,您可以对已安装的代码应用相同的修复程序,也可以使用早期版本,直到 3.1.3 被取代。