3👍
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.
3👍
def post_search(request):
results = [] # or None
total_results = 0 # or None
form = SearchForm(request.GET or None)
if 'query' in 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)
else:
return render(request, 'blog/post/search.html', {'form': form,})
else:
return render(request, 'blog/post/search.html', {'form': form,})
Python is pointing out that what will happen if the ‘if’ condition fails, and still you are using the variable ‘total_results’ in context. Therefore initialize it as 0 or none as you want. Similar with the ‘results’ variable too.
EDIT1: Since i don’t exactly know what you are trying to achieve, my best guess would be to use this code.
EDIT2: Template code changes
{% extends "blog/base.html" %}
{% block title %}Search{% endblock %}
{% block content %}
{% if results %}
<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 %}
1👍
I’ve gone through the same book, and noticed the same problem with that particular view. Here was my solution in the view. I left the template the way it was (in the book):
def post_search(request):
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()
total_results = results.count()
context = {'form':form, 'cd':cd, 'results':results, 'total_results':total_results}
return render (request, 'blog/post/search.html', context)
else:
form = SearchForm()
context = {'form':form}
return render (request, 'blog/post/search.html', context)
- [Django]-OAuth2 specification states that 'perms' should now be called 'scope'. Please update. Django Facebook connect
- [Django]-.Stay on SSL across redirects
1👍
had exactly the same issue … the code below works
def post_search(request):
results = []
total_results = 0
cd = None
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()
total_results = results.count()
return render(request, 'search/search.html', {'form':form,
'cd':cd,
'results':results,
'total_results':total_results,
})
But out of interest did you also find that the post_detail view produced similar errors ?? solved that one with this version of the code
def post_detail(request, year, month, day, post):
post = get_object_or_404(Post, slug=post,
status='published',
publish__year=year,
publish__month=month,
publish__day=day)
#list of active comments for this post
comments = post.comments.filter(active=True)
if request.method == 'POST':
# A comment was posted
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
#create comment object but don't save to DB
new_comment = comment_form.save(commit=False)
# assitgn comment to post
new_comment.post = post
# save the comment to the DB
new_comment.save()
else:
comment_form =CommentForm()
post_tags_ids = post.tags.values_list('id', flat=True)
similar_posts = Post.published.filter(tags__in=post_tags_ids).exclude(id=post.id)
similar_posts = similar_posts.annotate(same_tags=Count('tags')).order_by('-same_tags','-publish')[:4]
args = {}
args['post'] = post
args['comment_form']= comment_form
args['comments'] = comments
args['similar_posts'] = similar_posts
return render(request, 'detail.html', args )