I don’t mean to pick on Django (because I do really like it, working with Django is super productive), but it stuck out today.  I’m trying to safely increment a counter in a Django db.Model, and am having trouble finding documentation.

What I did find though, was a perfect example of how not to do it, right in the Django tutorial.  To save you the click, here’s the snipped up code:

def vote(request, poll_id):
    p = get_object_or_404(Poll, pk=poll_id)
    try:
        selected_choice = p.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # snip -- more code goes here
    else:
        selected_choice.votes += 1
        selected_choice.save()

This, as far as I can tell, is a classic race. Who knows what is happening behind the scenes between the .get() and the .save().

I guess I’ll continue the search for an atomic increment in Django…