Search code examples
pythondjangopostgresqldjango-formsrow-level-security

Django Row Level Locking For Model Forms


I am using Python 3.5, Django 1.8 and PostgreSql 9.4.

So I have one edit method where in get request I am rendering form and when user submit form it will get updated. Hers's the code

def edit_case(request, case_id):
    case = get_object_or_404(Case, pk=case_id)
    if request.method == 'POST':
        data = request.POST.copy()
        form = CaseEditForm(data, instance=case)
        if form.is_valid():
            res = form.save()
            return HttpResponseRedirect(reverse("case_list"))
    else:
        form = CaseEditForm(instance=case)
    variables = RequestContext(request, {
        "form": form,
    })
    return render_to_response(
        'sample/edit_case.html',
        variables,
    )

Now I want to add row level locking on it like if one user is updating something at the same time other will not be able update anything unless previous transaction succeeded Or if someone have any other better suggestions rather then using Pessimistic Locking.

I know about select_for_update but don't have any idea how it will get implemented in case of form.save()

Any help would be really appreciated


Solution

  • After so much research I have figured out the solution. So now while getting queryset against id I am using "select_for_update", something like this

    with transaction.atomic():
        case = get_object_or_404(Case.objects.select_for_update(), pk=case_id)
        form = CaseEditForm(data, instance=case)
            if form.is_valid():
                res = form.save()
                return HttpResponseRedirect(reverse("case_list"))
    

    So as you can see now I am fetching the query set object under the transaction and if any exception appear during transaction it will automatically rollback and Also as I am using select_for_update so it will lock the row until the transaction get succeeded or failed.

    If anyone have better suggestion then kindly share it.