如何使用Django进行手动提交

时间:2016-04-15 18:01:41

标签: django python-2.7

我想执行一个事务来删除一些值,然后在db中计数,如果结果是< 1,回滚,我尝试了以下代码:

@login_required
@csrf_exempt
@transaction.atomic
def update_user_groups(request):
    if request.POST:
        userId = request.POST['userId']
        groups = request.POST.getlist('groups[]')
        result = None
        with transaction.atomic():
            try:
                GroupsUsers.objects.filter(user_id=int(userId)).delete()
                for group in groups:
                    group_user = GroupsUsers()
                    group_user.user_id = userId
                    group_user.group_id = group
                    group_user.save()
                count = UsersInAdmin.objects.all().count()
                if count < 1:
                    transaction.commit()
                else:
                    transaction.rollback()
            except Exception, e:
                result = e
    return JsonResponse(result, safe=False)

谢谢,

2 个答案:

答案 0 :(得分:2)

无法在原子块内手动提交或回滚事务。

相反,您可以在原子块内引发异常。如果块完成,则将提交事务。如果引发异常,则将回滚该事务。在原子块之外,您可以捕获异常并继续查看。

try:
    with transaction.atomic():
        do_stuff()
        if ok_to_commit():
            pass
        else:
            raise ValueError()
except ValueError:
    pass

答案 1 :(得分:1)

我认为你应该再看看Django documentation about db transactions

最相关的评论如下:

  

避免在原子内捕获异常!

     

当退出原子块时,Django会查看它是正常退出还是有异常来确定是提交还是回滚。如果你捕获并处理原子块中的异常,你可以向Django隐瞒问题已经发生的事实。这可能会导致意外行为。

根据文档调整示例,看起来您应该嵌套trywith块,如下所示:

@transaction.atomic
def update_user_groups(request):
    # set your variables

    try:
        with transaction.atomic():
            # do your for loop
            if count < 1:
                # You should probably make a more descriptive, non-generic exception
                # see http://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python for more info
                raise Exception('Count is less than one')
    except:
        handle_exception()