2016-11-25 81 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響應發回給調用者。