J'essaie de créer une vue où j'enregistre un objet mais je voudrais annuler que enregistrer si une exception est levée. Voici ce que j'ai essayé:
class MyView(View):
@transation.atomic
def post(self, request, *args, **kwargs):
try:
some_object = SomeModel(...)
some_object.save()
if something:
raise exception.NotAcceptable()
# When the workflow comes into this condition, I think the previous save should be undome
# Whant am I missing?
except exception.NotAcceptable, e:
# do something
Qu'est-ce que je fais mal? même lorsque l'exception est levée some_object
est toujours dans DataBase.
Résumer, @transaction.atomic
exécutera une transaction sur la base de données si votre vue produit une réponse sans erreur. Parce que vous interceptez l'exception vous-même, il semble Django que votre vue s'est bien exécutée.
Si vous interceptez l'exception, vous devez la gérer vous-même: Contrôle des transactions
Si vous devez produire une réponse json appropriée en cas d'échec:
from Django.db import SomeError, transaction
def viewfunc(request):
do_something()
try:
with transaction.atomic():
thing_that_might_fail()
except SomeError:
handle_exception()
render_response()
Cependant, si une exception se produit dans une fonction décorée avec transaction.atomic, alors vous n'avez rien à faire, cela va revenir automatiquement au point de sauvegarde créé par le décorateur avant d'exécuter votre fonction , comme documenté :
atomic nous permet de créer un bloc de code au sein duquel l'atomicité sur la base de données est garantie. Si le bloc de code est terminé avec succès, les modifications sont validées dans la base de données. S'il existe une exception, les modifications sont annulées.
Si l'exception est interceptée dans un bloc excepté, alors elle devrait être re-augmentée pour qu'atomic l'attrape et fasse le rollback, c'est-à-dire:
try:
some_object = SomeModel(...)
some_object.save()
if something:
raise exception.NotAcceptable()
# When the workflow comes into this condition, I think the previous save should be undome
# Whant am I missing?
except exception.NotAcceptable, e:
# do something
raise # re-raise the exception to make transaction.atomic rollback
De plus, si vous voulez plus de contrôle, vous pouvez revenir manuellement à point de sauvegarde précédemment défini , c'est-à-dire:
class MyView(View):
def post(self, request, *args, **kwargs):
sid = transaction.savepoint()
some_object = SomeModel(...)
some_object.save()
if something:
transaction.savepoint_rollback(sid)
else:
try:
# In worst case scenario, this might fail too
transaction.savepoint_commit(sid)
except IntegrityError:
transaction.savepoint_rollback(sid)