2016-11-25 78 views
0

我以前是a similar questio n,但我说得不对,这就是为什么需要在新帖子中阐明它。Django中的异常处理和原子请求

考虑以下Django配置和一个视图:

settings.py

DATABASES = { 
    'default': { 
     # ... 
     'ATOMIC_REQUESTS': True, 
    }, 

视图:

def my_view(request): 
    foo = Foo.objects.get(id = 1) 
    foo.some_field = 'new value' 
    foo.save() 
    if some_condition(): 
     # ... 
    else: 
     return JsonResponse(json.dumps('Cusom message', ensure_ascii=False), 
          status = 500, 
          safe = False) 

这段代码的问题是,如果是some_conditionfoo对象被更新不是真的,但我期望交易回滚,因为我发送状态500.任何人都可以给我一个暗示我在做什么这里错了吗?

+2

发送500不会导致事务回滚。 –

+2

不要使用原子请求;使用['atomic'](https://docs.djangoproject.com/en/1.10/topics/db/transactions/#django.db.transaction.atomic)上下文管理器将相关代码显式包装并发送您需要的任何响应。 –

+1

丹尼尔,能否请您提供一个代码片段,以便我确信我实现您的建议是最合适的方式 –

回答

1

扩大对@ Daniel的评论,这里是你如何可以用自定义的原子块做到这一点:

from django.db import transaction 


def my_view(request): 
    try: 
     with transaction.atomic(): 
      foo = Foo.objects.get(id = 1) 
      foo.some_field = 'new value' 
      foo.save() 
      if not some_condition(): 
       raise Exception('This exception is to force rollback') 
      # ... 
    except Exception: 
     return JsonResponse(json.dumps('Cusom message', ensure_ascii=False), 
          status = 500, 
          safe = False) 

所以这里的技巧是,如果由于一个异常with transaction.atomic()块退出时,任何语句中执行该事务块会回滚。我们在with block之外捕获异常,以便我们可以将500响应发回给调用者。