NoReverseMatch in Django [Newbie] - python

I've been trying to figure this out for a while now but I feel like I don't know the framework well enough to debug this myself.
Basically I'm creating a little blog style site and I'm trying to create a list of posts which can link to the page to read the post itself.
I have a for loop in my template:
templates/home.py
<h1>Home Page</h1>
<p>welcome to the ven home page, {{ username }}!</p>
Click here to log out
<br>
Click here to create a post
<h2>Posts:</h2>
{% for post in posts %}
<div>
<hr>
<h4>{{post.title}}</h4>
<p>{{post.body}}</p>
<p><i>{{post.tags}}</i></p>
</div>
{% endfor%}
It's the line <h4>{{post.title}}</h4> which is causing the problem. I'm getting the error
Reverse for 'show' with keyword arguments '{'id': 1}' not found. 1
pattern(s) tried: ['posts/(?P<post_id>\\d+)/view/$']
here is my urls file
url(r'^$', views.CreateFormView.as_view(), name='create'),
url(r'^(?P<post_id>\d+)/view/$', views.show_post, name='show')
The create method link works fine
and here is the view which loads the template:
def home(request):
if not request.user.is_authenticated:
return redirect('users:login')
posts = Post.objects.all()
username = request.user.username
return render(request, 'ven/home.html', {'username': username, 'posts':
posts})
If more information is needed then let me know and I will provide it.
All other answers have said that this error is to do with the namespace, but it's working fine with the create link so I'm stumped.
Thanks in advance!

The argument names are mismatching.
You'd want to change <h4>{{post.title}}</h4>
to
<h4>{{post.title}}</h4>
Since in urls.py the show url is defined as '^(?P<post_id>\d+)/view/$'.

Related

Django error no reverse match with arguments '('',)'

I feel kinda bad using my first post as a cry for help but hey, im certainly not the first lulz, anyway, im teaching myself python/django and im really stuck atm and ive been slogging through problems myself lately and wasting a lot of time doing it and this one has me stuck.
Im getting the error: NoReverseMatch at /messages/newreply/1/
Reverse for 'newreply' with arguments '('',)' not found. 1 pattern(s) tried: ['messages/newreply/(?P<post_id>[0-9]+)/\Z']
This is my url file;
app_name = 'board'
urlpatterns = [
path('', views.index, name='index'),
path('<int:post_id>/', views.postdetail, name='detail'),
path('newmsg/', views.newmsg, name='newmsg'),
path('newreply/<int:post_id>/', views.newreply, name='newreply')
view
def newreply(request, post_id):
post = Post.objects.get(id=post_id)
if request.method != "POST":
form = ReplyForm()
else:
form = ReplyForm(data=request.POST)
if form.is_valid():
newreply= form.save(commit=False)
newreply.post = post
newreply.save()
return redirect('board:index')
context = {'form':form}
return render(request, 'board/newreply.html', context)
template;
{% extends 'pages/base.html' %}
{% block content %}
<p>Add your reply here</p>
<form action="{% url 'board:newreply' post.id %}"method ='post'>
{% csrf_token %}
{{ form.as_p }}
<button name = "submit">Add post</button>
</form>
{% endblock content %}
Ive tried so many things now im not even sure where i began anymore so id really appreciate any help, especially knowing why its actually happening as ive read through a few posts with the same type of error but trying the solutions posted has produced other errors for me.
Thank you!
It is indeed a useless and annoying error. Usually, it means you haven't passed something in the context of the request. In this case, the post object.
context = {'form':form, 'post': post}
return render(request, 'board/newreply.html', context)

django parameter causing the wrong template and view to render

Overview / Problem:
Hi! The wrong template and view are loading every time I click the check_tier_level link in my template.
When that parameter is in, it loads the home view with "check_tier_level" as the special_message, even though my links go to the view for check_tier_level. If I click any of the form buttons to grant access, the proper message shows up in that spot. I just can't check the level.
The app works fine and renders the right template / view only when I remove the special_message parameter from the urlpattern and view.
The only other lead I have on this is that the url in the browser will also look like http://127.0.0.1:8000/tiered_access_app/Tier 1 granted!/, instead of having the characters escaped with %20 and so on.
My goal
The whole reason I want to keep that parameter in is so a special_message can notify users of the latest update based on their actions. If anyone knows a better way to do this without making a whole new view / template (which I know is a solution, and how to do it), I'd like to know how. Anyways, here's my code:
urlpatterns.py
path('', views.home, name='home'),
path('<str:special_message>/', views.home, name='home_special_message'),
path('check_tier_level/', views.check_tier_level, name='check_tier_level'),
path('check_tier_level/gain_access/', views.gain_access, name='gain_access'),
views.py
def home(request, special_message=None):
return render(request, 'tiered_access_app/home.html', {'special_message': special_message})
def check_tier_level(request):
current_user = request.user
try:
find_user = TieredAppCustomUser.objects.get(user=current_user)
if find_user.tier_choice == 'tier1':
return render(request, 'tiered_access_app/check_tier_level.html', {'level_1': 'You have access to level 1.'})
# and so on with other levels...
except ObjectDoesNotExist:
pass
return render(request, 'tiered_access_app/check_tier_level.html', {'no_access': 'You don\'t have access to the content here yet.'})
home.html
{% if special_message %}
<h2>{{ special_message }}</h2>
{% endif %}
<form action="{% url 'tiered_access_app:gain_access' %}" method="POST">
{% csrf_token %}
<label>Check level 1 access</label>
<!-- *******PROBLEM WITH LINK HERE******** -->
<p>Try to access level 1 first. You won't be allowed unless you gain access first, by clicking the button below.</p>
<!-- *******PROBLEM WITH LINK HERE******** -->
<input type="hidden" value='1' name="tier_level">
<input type="submit" value="Enable level 1">
</form>
I FIGURED IT OUT:
All I had to do was change my url patterns into the following order:
path('', views.home, name='home'),
path('check_tier_level/', views.check_tier_level, name='check_tier_level'),
path('check_tier_level/gain_access/', views.gain_access, name='gain_access'),
path('<str:special_message>/', views.home, name='home_special_message'),
The only difference here and what I have below, is the position of the 2nd function that goes to home. I'm going to leave this question up in case someone else comes across this same problem. I don't know why this made it work, but it did. Now everything works perfectly.

Django passing data from one app to another?

I am using django-allauth for my authentication. I have a dashboard which has many links.
user.html
`{% include 'sidebar.html' %}
<h1>Profile View</h1>
<p>{{ profile.username }}</p>`
change_password.html
`{% include 'sidebar.html' %}
<h2>Change Password</h2>
<p>{{ profile.username }}</p>`
sidebar.html
`Profile View
Change Password`
views.py
class ProfileView(DetailView):
template_name = "user.html"
queryset = User.objects.all()
context_object_name = 'profile'
slug_field = "username"
change password view is from django-allauth. How can i pass the the username from the ProfileView to the change password view so that i can display in the change_password.html page.
Main Problem
Since i have been including sidebar.html to both the views, it works good in ProfileView but when i navigate to change_password view i get the following error
Reverse for 'profile_view' with keyword arguments '{'slug': ''}' not found. 1 pattern(s) tried: ['(?P[-\w.#+-]+)/$']
the error does not show in ProfileView because the profile.username returns a value, but when i navigate to change_password view i get the above error because the profile context object only passes in that particular view. i want to use that context_object through out the project.
Is there a simple way to do it? other than build a JSON API?
I just had a quick look at the template tags provided by the allauth app. I haven't tested this (nor do I use the project) but this looks like what you are looking for.
In your template, any template...
{% load account %} {# this should be near the top with any other load tags #}
{# this can be anywhere in the template. I'm not positive what it returns but it looks like it is the username. #}
<p>
{% user_display user %}
</p>
I found the answer here.
I got it working, Thank you #teewuane
sidebar.html
Profile View
replaced as
Profile View

Django - Passing argument through href for URL dispatcher?

So I am working on a website where at some point I do a search and list a list of textbooks on the page. From there I want the user to be able to click on a textbook and each textbook will have it's own details page. I have been trying to work with Django's URL dispatcher but I am having difficulties. Code and description below.
results.html
<table class="table">
{% for items in results %}
<tr><td>{{items.textbook_name}}</td><td>{{items.class_name}}</td><td>{{items.author}}</td><td>{{items.isbn}}</td><td>></td></tr>
{% endfor %}
</table>
Views.py
def textbook(request, text_name):
return render_to_response(
'textchange/textbook.html',
locals(),
context_instance=RequestContext(request)
)
Urls.py
url(r'^results/(?P<text_name>\w+)/$', views.textbook, name="textbook"),
From my understanding I thought I was passing the items.textbook_name as text_name to urls from the html and then views would be called with text_name as an argument but it is not working. I might be a little backwards here. I need the textbook_name from the textbook the user clicks on so on the details page I can display all it's information from the database.
Thanks.
Quick explanation.
Let's say that your url doesn't need text_name parameter, so that:
{% url 'textchange:textbook' %}?text_name={{items.textbook_name}}
will result in:
/results/?text_name=some-name
text_name won't get passed to url tag, it was simply glued on the end of url.
To pass text_name into url, and build proper url, you should do that:
{% url 'textchange:textbook' text_name=items.textbook_name %}
and it will result in url:
/results/some-name/

Django context not rendering

I've got a Django template in HTML. I would like to pass a variable to this template using a context. However, when I render the template Django fills the spaces that reference this variable with the string specified by the TEMPLATE_STRING_IF_INVALID setting (I tested this).
Here's the relevant URLconf:
from django.conf.urls import patterns, url
from users import views
urlpatterns = patterns('',
url(r'^$', views.users),
url(r'(?P<pk>\d+)/$', views.userdetail),
)
and here's the view it references:
from django.template import RequestContext, loader
...
def userdetail(request, pk):
user = get_object_or_404(User, pk=pk)
template = loader.get_template('users/userdetail.html')
context = RequestContext(request, {'user': user})
return HttpResponse(template.render(context))
I'm fairly certain it's due to a syntax error in specifying the context but after looking at it for an hour I can't find one. I'm happy to post additional code if you think it may be relevant. Can anyone spot my mistake?
Template for those interested:
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif%}
<h1> You are viewing the page for the individual user {{ user.name }} </h1>
This user has created the following posts:
{% for post in user.post_list %}
{{ post.title }}</li>
{% endfor %}
<p>
Created on {{ user.creation_date }}
</p>
The OP wrote:
My supervisor just came around and fixed it really quickly. The issue is that templates have some predefined keywords. User is one of these keywords so django was upset that I was passing it {'user':user} in the context. Changing to {'customuser':user} avoids the collision with the django keyword and fixes this issue.

Categories

Resources