justin
justin

Reputation: 1699

Python Django UnboundLocalError

I'm new with django.

I have this code under my views.py

poll_list = []

@login_required
@never_cache
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):
        return detail(request, poll_id, error_message="You didn't select a choice.")
    else:
        if request.session.get('voted_on', False):
            poll_list = []
            request.session['voted_on'] = poll_list

        if poll_id in request.session.get('voted_on', []):
            return detail(request, poll_id, has_voted="You have already voted.")

        selected_choice.votes += 1
        selected_choice.save()

        poll_list.append(poll_id)
        request.session['voted_on'] = poll_list
        return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
    return HttpResponse("You're voting on poll %s." % poll_id) 

I got this error:

UnboundLocalError at /polls/3/vote/
local variable 'poll_list' referenced before assignment

Help me please.. I don't understand why I keep getting this error. Thanks

Upvotes: 0

Views: 296

Answers (2)

Burhan Khalid
Burhan Khalid

Reputation: 174624

You are getting this error because in your method, you are only creating the variable poll_list in the if conditional. So if that conditional is false, there is no poll_list, so when you try to use it in poll_list.append(poll_id), Python gives you that error.

I think what you are trying to do is use the global variable that you have declared outside the method, which is not the right way to do what you want.

The "wrong" fix is to add global poll_list in your method.

The correct fix is to restructure your method:

# poll_list = [] - not needed

@login_required
@never_cache
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):
        return detail(request, poll_id, error_message="You didn't select a choice.")
    else:
        poll_list = request.session.get('voted_on', [])

        if poll_id in poll_list:
            return detail(request, poll_id, has_voted="You have already voted.")

        selected_choice.votes += 1
        selected_choice.save()

        poll_list.append(poll_id)
        request.session['voted_on'] = poll_list
        return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
    return HttpResponse("You're voting on poll %s." % poll_id) 

Upvotes: 1

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798686

Assigning to the name makes the compiler think that it's local. Use global poll_list at the beginning of the function to change this.

But this will cause other issues, so you should rearchitect the function regardless.

Upvotes: 0

Related Questions