Django Noreversematch And General Notes
My ArchEnemy
NoReverseMatch today happened a couple of times, here’s what I learnt:
- whatever happens in url liquid tag, should happens in url.py reflecting on paths and diff names, AS WELL AS views.py function’s arguments. Mainly it’s the argument issue
- 2 ways to passing arguments in liquid url tag: with or without ‘=’, both are fine, I prefer without, simpler
- argument passing order DOES matter, EVERYWHERE
Other Notes
I spent most of the day debugging this searching function: view.py
# Q helps to filter through objects with options of 'or'
from django.db.models import Q
def search(request, query=None, topic_pk=None):
# if no-input submission --> redirect to topics for users to browse
if request.GET.get('query') == '':
return redirect('forum:topics')
# if user searching from nav bar, get the request query value stored properly
if query == None:
query = request.GET.get('query')
# search through all Post objects, in titles AND contents, because of Q
search_result_posts = Post.objects.filter(
Q(title__icontains=query) |
Q(content__icontains=query) |
Q(date_added__icontains=query))
# because there are only a few topics,
# use filtered posts to determine topics for displaying in the sidebar
search_result_topics = []
for post in search_result_posts:
if post.topic not in search_result_topics:
search_result_topics.append(post.topic)
# passing an empty topic if topic_pk=None
search_result_topic = {}
# if to check results in a specific topic
if topic_pk != None:
# make sure this topic exists and override the default value
search_result_topic = get_object_or_404(Topic, pk=topic_pk)
# search through all the posts in this topic, and override previous search_results_posts
search_result_posts = search_result_topic.post_set.filter(
Q(title__icontains=query) |
Q(content__icontains=query))
return render(request, 'forum/search.html', {
'search_result_posts': search_result_posts,
'search_result_topics': search_result_topics,
'search_result_topic': search_result_topic,
'query': query})
base.html in attr action, the url points at ‘forum:search’
<form class="form-inline m-0 float-right" action="{ url 'forum:search' }" method="GET">
<input name="query" class="form-control mr-2" style="height:38px" type="text" placeholder="Topic Searcher...">
<button class="btn my-2 ml-n5" type="submit"><i class="fa fa-search"></i></button>
</form>
search.html whereas in a link after the search results are rendered, the url points at ‘forum:search_topic’
<a class="btn btn-outline-secondary rounded-lg mb-2 p-2 shadow-sm" style="width:90%;"
href="{ url 'forum:search_topic' query topic.pk }"></a>
url.py
path('search/', views.search, name='search'),
path('search/<query>/topic_<int:topic_pk>/', views.search, name='search_topic'),
Note: <query> should be passed in path in the same order as it is in view function