losee losee - 6 months ago 13
Python Question

I keep getting the following error "local variable 'total_results' referenced before assignment"

I am new to django and python, I am following a django tutorial and I keep getting the following error

UnboundLocalError at /blog/search/
local variable 'total_results' referenced before assignment


heres my code

def post_search(request):
form = SearchForm()
if 'query' in request.GET:
form = SearchForm(request.GET)
if form.is_valid():
cd = form.cleaned_data
results = SearchQuerySet().models(Post)\
.filter(content=cd['query']).load_all()
# count total results
total_results = results.count()
template = 'blog/post/search.html'
context = {
'form': form,
'cd': cd,
'results': results,
'total_results': total_results
}
return render(request, template, context)


I also tried it like this origanally because that's how the tutorial had it

return render(request, template, {
'form': form,
'cd': cd,
'results': results,
'total_results': total_results
})


but that also didn't work

I understand what the error message is saying but this is how the tutorial has it. What's the proper syntax to make this work. all guidance is welcome

EDIT: here is the template code

{% extends "blog/base.html" %}
{% block title %}Search{% endblock %}
{% block content %}
{% if "query" in request.GET %}
<h1>Posts containing "{{ cd.query }}"</h1>
<h3>Found {{ total_results }} result{{ total_results|pluralize}}</h3>
{% for result in results %}
{% with post=result.object %}
<h4><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4>
{{ post.body|truncatewords:5 }}
{% endwith %}
{% empty %}
<p>There are no results for your query.</p>
{% endfor %}
<p><a href="{% url 'blog:post_search' %}">Search again</a></p>
{% else %}
<h1>Search for posts</h1>
<form action="." method="get">
{{ form.as_p }}
<input type="submit" value="Search">
</form>
{% endif %}
{% endblock %}

Answer

If there would not be query GET parameter passed, or the form would not pass validation - in this case total_results and results would not be defined. You need to either provide the default values for that case, e.g.:

def post_search(request):
    results = []
    total_results = 0

    form = SearchForm()
    if 'query' in request.GET:
        form = SearchForm(request.GET)
        if form.is_valid():
            cd = form.cleaned_data
            results = SearchQuerySet().models(Post)\
                .filter(content=cd['query']).load_all()
            # count total results
            total_results = results.count()
    template = 'blog/post/search.html'
    context = {
       'form': form,
       'cd': cd,
       'results': results,
       'total_results': total_results
    }
    return render(request, template, context)

Or, throw a specific "validation" error in case there is no query parameter or form is not valid.