Django "remove hardcoded urls in templates" not working - python

I'm checking out django for the first time following the tutorial https://docs.djangoproject.com/en/1.6/intro/tutorial03/
So far it's been plain sailing. I've hit a snag at the Remove hard coded urls section. I'm using Django 1.6.6.
When I change the hardcoded url from:
<li>{{ poll.question }}</li>
to:
<li>{{ poll.question }}</li>
I get a 404 error as follows:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/polls/%7B%%20url%20'detail'%20poll.id%20%7D
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^polls/ ^$ [name='index']
^polls/ ^(?P<poll_id>\d+)/$ [name='detail']
^polls/ ^(?P<poll_id>\d+)/results/$ [name='results']
^polls/ ^(?P<poll_id>\d+)/vote/$ [name='vote']
^admin/
The current URL, polls/{% url 'detail' poll.id }, didn't match any of these.
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.
The url that shows up in the address bar is
mylocalenv/polls/%7B%%20url%20%27detail%27%20poll.id%20%7D
I've tried removing the quotes from 'detail' but given I'm on django 1.6.6 I shouldn't need to. It didn't work either. I've also tried skipping ahead a bit and including the /polls/ namespace in urls.py but again, no joy.
My urls.py file looks like this:
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
# ex: /polls/
url(r'^$', views.index, name='index'),
# ex: /polls/5/
url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<poll_id>\d+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)
The exact code in my index.html template is:
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Got it
But frustratingly I have no idea why. Out of desperation in my index.html I started playing around with the index.html file on this line:
<li>{{ poll.question }}</li>
For no logical reason I changed poll.id to poll_id. Reloading broke index.html as I expected. When I changed it back to poll.id everything works. This makes no sense. I even ctrl^z back to the index.html that previously wasn't working and now that's working too. I restarted the server before each check. I'm annoyed. But at least it's working.

This line in the trace back suggests you have missed out the % before the closing curly brace.
The current URL, polls/{% url 'detail' poll.id }, didn't match any of these.

Even, I was facing this problem and for me the reason was that I gave space between { % and % }, where as the correct syntax is {% and %}. For completeness I have given the correct and incorrect syntax below -
correct syntax - <li>{{ poll.question }}</li>
incorrect syntax - <li>{{ poll.question }}</li>

check you polls/urls.py file, make sure your urlpatterns is [], not {}
urlpatterns = [
path('', views.index, name='index'),
]

I just restarted the server and interestingly it just worked.

Related

Python/Django "page not found" error: "The current path, ... , didn’t match any of these."

I'm learning Chapter 18 in Python Crash Course by Eric Matthes. I am using Django 4.0.1 and the book uses is 2.2.0 so I see that other people are having similar issues as me with this section.
In other similar stackoverflow questions on this issue, proposed solutions using url instead of path seem also outdated. The solutions on the website therefore are unfortunately not helping me.
Problem:
when I open http://localhost:8000/ and I click on "topics" I get the 404 not found error as follows:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/(%25%20url%20'learning_logs:topics'%20%25%7D
Using the URLconf defined in learning_log.urls, Django tried these URL patterns, in this order:
admin/
[name='index']
topics/ [name='topics']
The current path, (% url 'learning_logs:topics' %}, didn’t match any of these.
However, navigating manually to http://localhost:8000/topics shows me the page as intended. I believe this is an issue due to my urls.py located in my app folder.
Here is my urls.py in learning_logs (app), where I think the issue lies:
from django.urls import path
from . import views
app_name = 'learning_logs'
urlpatterns = [
#Home page
path('', views.index, name='index'),
#Page that shows all topics.
path('topics/', views.topics, name='topics'),
]
Here is my urls.py in learning_log (main project):
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('learning_logs.urls')),
]
views.py
from django.shortcuts import render
from .models import Topic
# Create your views here.
def index(request):
"""The home page for Learning Log."""
return render(request, 'learning_logs/index.html')
def topics(request):
"""Show all topics."""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context)
base.html found in template/learning_logs folder:
<p>
<a href="{% url 'learning_logs:index' %}" >Learning Log</a> -
<a href="(% url 'learning_logs:topics' %}" >Topics</a>
</p>
{% block content %} {% endblock content %}
topics.html
{% extends "learning_logs/base.html" %}
{% block content %}
<p> Topics </p>
<ul>
{% for topic in topics %}
<li> {{topic}}</li>
{% empty %}
<li> No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}
and finally index.html:
{% extends "learning_logs/base.html" %}
{% block content %}
<p>Learning Log helps you keep track of your learning, for any topic you're
learning about.</p>
{% endblock content %}
The comment below my question by Willem Van Onsem answered my question, turns out it was a typo.
The Topics did not start the url template tagb with {%... –
Willem Van Onsem

Why does the hard-coded url work but not the name-spaced url in Django?

I need someone that really knows their Django. So I can always give more detail if it's necessary but long story short, I'm trying to link to urls using django's url tag and I get a NoReverseMatch exception everytime.
<ul>
{% for item in results %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
BUT, when I use the hardcoded url, this works perfectly fine:
<ul>
{% for item in results %}
<li>{{ item.title }}</li>
{% endfor %}
</ul>
This is what the url.py module looks like:
from django.urls import path
from . import views
app_name = 'cards'
urlpatterns = [
path('', views.index, name='index'),
path('search/', views.search, name='search'),
path('search-results/<keywords>/', views.search_results, name='search-results'),
path('stats/<item_title>/', views.stats, name='stats')
]
Does anyone have any idea why this might be happening? Let me know if you need more details. Any help is appreciated, thanks!

Getting NoReverseMatch Error

I have an app that is going to display some information about people in my group. I'm getting a NoReverseMatch error when trying to use the url tag in my index.html. If I do not use the url tag, but specify the root, I do not receive the error.
The error says:
NoReverseMatch at /
Reverse for 'specialist' with arguments '(1,)' and keyword arguments '{}' not found. 1 pattern(s) tried: ['$(?P[0-9]+)/']
Here is are the urls.py files.
From the main wi_tech urls.py:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^$', include('person.urls')),
url(r'^tech/', include('person.urls')),
url(r'^admin/', admin.site.urls),
]
From the 'person' app urls.py:
from django.conf.urls import url
from . import views
app_name = 'person'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='specialist'),
]
My views.py file looks like this:
from django.views import generic
from .models import Specialist
class IndexView(generic.ListView):
template_name = 'person/index.html'
context_object_name = 'person_list'
def get_queryset(self):
"""Return all specialists"""
return Specialist.objects.order_by('id')
class DetailView(generic.DetailView):
model = Specialist
template_name = 'person/detail.html'
And my index.html page looks like this:
{% if person_list %}
<ul>
{% for specialist in person_list %}
<li> {{ specialist }}</li>
{% endfor %}
</ul>
{% else %}
<p>No specialists are available.</p>
{% endif %}
If I change my tag in index.html to this, it works:
<li> {{ specialist }}</li>
Obviously this isn't an ideal situation in case the web root ever changes. I've reviewed a lot of SO questions on this, and nothing seems to match. I think the issue is the "$" in the beginning of the regex, but I don't see where that's coming from.
Specifically, I used this link as a really good reference point, but came up empty looking through my code.
what is NoReverseMatch and how do i fix it
Clearly there's something I'm missing.
Could it be the additional / at the end of the URL?
url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='specialist')
The one after your primary key modifier. When you click the URL (with the (% url ':' model.name %)) what URL comes up in your browser?
I ended up scrapping this implementation, and going with a flatter structure whereby all models, views and templates are in the same application. I have not had this problem in the new design.

Alternative/ How to use {% url %} in django 1.8?

I'm learning django on version 1.8.
In their documentation they suggest to use {% url %} template tag in order to avoid hardcoding the url. But it is not working in the v1.8, and confirmed that it is deprecated in this version.
https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#url
Does anyone know any alternative ?
Update:
p_index.html
{% if latest_question_list %}
<ul>
{% for que in latest_question_list %}
<li>{{ que.question_text }}</li>
{% endfor %}
</ul>
{% else %}
<p> No polls questions are availabe. </p>
{% endif %}
Above code gives me this error: 'str' object has no attribute 'regex'
When I change the href line as below, works fine!
<li>{{ que.question_text }}</li>
urlpatterns in polls app:
urlpatterns = [
url(r'^$', views.index, name='view_index'),
# ex: /polls/5/
url(r'^(?P<q_no>[0-9]+)/$', views.detail, name='detail'),
# ex: /polls/5/results/
url(r'^(?P<q_no>[0-9]+)/results/$', views.results, name='results'),
# ex: /polls/5/vote/
url(r'^(?P<q_no>[0-9]+)/vote/$', views.vote, name='vote'),
]
The main urls.py is as below :
urlpatterns = [
url(r'^$', 'home.views.index'),
url(r'^polls/', include('polls.urls', namespace = 'polls')),
url(r'^android/start', 'testpage.views.androidStart'),
url(r'^admin/', include(admin.site.urls)),
]
I think you got this wrong. The {% url %} tag is not depercated to my best of knowledge, and I have never heard of any alternative. What is deprecated is the syntax to pass a dotted Python path:
Deprecated since version 1.8:
You can also pass a dotted Python path to a view function, but this syntax is deprecated and will be removed in Django 1.10:
{% url 'path.to.some_view' v1 v2 %}

404 error when viewing details of a poll in Django

I'm working through the Django tutorial anf. For some reason, if I try to manually type in the URL like so: http://localhost:8000/polls/1/ I can view the poll (in this case the id of the poll is 1). But if I'm at the index of all the polls, which would be the URL: http://localhost:8000/polls and I try to click on one of the polls, it takes me to an error page with the following:
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^polls/ ^$ [name='index']
^polls/ ^(?P<pk>\d+)/$ [name='detail']
^polls/ ^(?P<pk>\d+)/results/$ [name='results']
^polls/ ^(?P<poll_id>\d+)/vote/$ [name='vote']
^admin/
The current URL, polls/{% url 'polls:detail' poll.id % }, didn't match any of these.
Here's my polls/urls file:
urlpatterns = patterns('',
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'),
url(r'^(?P<poll_id>\d+)/vote/$', views.vote, name='vote'),
)
And my mysite/urls file:
urlpatterns = patterns('',
url(r'^polls/', include('polls.urls', namespace='polls')),
url(r'^admin/', include(admin.site.urls)),
)
And my template file:
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
I've seen similar questions but it doesn't seem that they apply to me. Why does it work when I type in the URL but not when I click on the link that should take me to the same place?
You have space between % and }, try this
<a href="{% url 'polls:detail' poll.id %}">

Categories