Django - Reverse resolution of URL throws 'NoReverseMatch' - python

I have url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic') in urls.py but when I try to go to localhost:8000/topics/1 it tells me that it tried one pattern: topics/(?P<topic_id>**\\**d+)/$
I would think it would be topics/(?P<topic_id>**\**d+)/$
I'm using a book called The Python Crash Course (1st edition)(ch. 18).
This is a local server using Django 1.11 with Python. I've tried a lot of reformatting on the url pattern but I am new at this so I don't know what else to do.
...
urlpatterns = [
url(r'^$', views.index, name='index'),
# Show all topics.
url(r'^topics/$', views.topics, name='topics'),
# Detail page for a single topic.
url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'),
]
I expected it to pop up with the correct page but it always says 'NoReverseMatch at /topics/01/'

So you've forgotten the trailing slash at the end of your URL, hence why it's not matching.
You could remove the slash from the regex, but that would shift the problem: it wouldn't work if you put a slash.
I guess you could end the pattern with /?$, but here's a solution that's probably more robust: Jiaaro's answer to: django urls without a trailing slash do not redirect
Basically:
check your APPEND_SLASH setting in the settings.py file

Related

Django page not found (404) in my core/urls.py file. Only works when the urls are rearranged

I am relatively new to Django. I've set up my URLs in my core/urls.py file this way and I do get a 404 error when I opened localhost:8000/posts/ on the browser. Code is shown here
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<slug:slug>/', views.SingleView.as_view(), name='single'),
path('posts/', views.PostsView.as_view(), name='posts'),
]
However, everything works fine when I reverse the slug and posts/ to make the posts come before the slug. Like this:
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('posts/', views.PostsView.as_view(), name='posts'),
path('<slug:slug>/', views.SingleView.as_view(), name='single'),
]
Please help me figure it out.
That's how Django (and most other frameworks) work. When a request comes in, Django will check the routes that you specified and it uses the same order that you specified them. So in your first example, '' is the first one and then '<slug:slug>/' and 'posts/' after that. this means that every time a request comes in, Django will check for routes on that order. basically how a for loop works:
Example URL: yoursite.com/posts/
Path: "posts/"
routes = ["", "<slug:slug>/", "posts/"]
path = "posts/"
for route in routes:
if route == path:
# use view for this route
return
So in this case, it will match with index 1 which is <slug:slug>/, and returns the view specified for it.
Now to understand why <slug:slug>/ == "posts/" returns True you need to understand what slug means in Django:
slug - Matches any slug string consisting of ASCII letters or numbers, plus the hyphen and underscore characters. https://docs.djangoproject.com/en/3.1/topics/http/urls/#example
So it will accept any path that matches those requirements and posts/ actually matches those requirements. Django doesn't check any other routes if it finds a match so it will never gets to path('posts/', views.PostsView.as_view(), name='posts') because '<slug:slug>/' has higher priority being in the smaller index over 'posts/'. And you probably check for that slug in your models which isn't there so it will return a 404.
By changing the route order, you change the routes to ["", "posts/", "<slug:slug>/"]. Now "posts/" has higher priority and django will use PostsView.

Django app urls not working properly

I have the following base urls file:
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^agenda/', include('planner.urls', namespace='planner', app_name='planner'))
]
And my planner app contains the following urls:
urlpatterns = patterns('',
url(r'^', SkirmList.as_view(), name='agenda'),
url(r'^skirm/(?P<pk>\d+)/$', SkirmDetailView.as_view(), name='skirmdetailview'),
)
The problem I am having is when going to: http://localhost:8000/agenda/skirm/41/
It keeps loading the SkirmList view instead of the SkirmDetailView.
It's propably obvious to most but I am a beginner with Django. Any help is appreciated, thanks
The regex r'^' matches any string. It just says the string needs to have a start. Every string has a start, so...
You need to include an end anchor as well:
url(r'^$', ...)
This regex looks for the start of the string, followed immediately by the end, i.e. an empty string. It won't match the /agenda/skirm/41/ url.

URL Regular Expression mismatch

I am trying to learn Django and I am currently stuck in an issue.
I created an app Contact and run the server, I get the error.
The error page displayed by server:
The urls.py file in the app Contact
urls.py in conatct
When the pattern in urls.py is
urlpatterns =[url(r'^$', views.form, name ='form')]
it works properly, but not with other pattern shown in the picture
Your help would be greatly appreciated.
The Page not found error message tells you what went wrong: For the URL (/contact) you requested, Django was unable to find a suitable view. Because you have debugging enabled, you get some information, including a list of registered views.
First things first: You probably have url(r'^contact/', include('contact.urls')) somewhere in your top level urls.py. This makes the URLs defined in the contact/urls.py available under the prefix /contact.
With
urlpatterns = [
url(r'^form/', views.form, name='form'),
]
in contact/urls.py you are telling Django that you want urls starting with contact/form/ to be handled by views.form.
Consequently, when you access http://localhost:8000/contact/ in your browser, there is no view associated with that URL, hence the 404. Your view is reacting to to http://localhost:8000/contact/form, not http://localhost:8000/contact.
When you change the URL pattern to
urlpatterns = [
url(r'^$', views.form, name='form'),
]
you modify the URL views.form reacts to.

Django urlpatterns/include() loading wrong view

Website has a homepage in addition to several data-driven apps. No problem. But as I'm trying to add in other non-data-driven pages (about, mission statement, etc) I'm having trouble with by url directs.
settings.py url patterns includes:
url(r'^$', include('home.urls')),
url(r'^mission/$', include('home.urls')),
home/urls.py includes:
url(r'^$', views.index, name='index'),
url(r'^mission/$', views.mission, name='mission'),
Directing the browser to the homepage loads the index view as it should, but directing the browser to /mission/ also loads the index view.
I realize I'm probably missing something small (and fundamental) here, but I've read over the docs for the hundredth time and read about a lot of other people's questions about urlpatterns, but I just can't figure out what's going on. The include() statement in settings.py doesn't seem to be the problem. Since the home index view loads it's obviously being directed to home/urls.py, and that file is so simple that I just can't see what the problem would be.
Could someone please educate me so I can move on to my next Django brick to the face? I appreciate it.
SOLVED - Thank you Sohan Jain
Actual issue was use of r'^$' in settings URLPATTERNS rather than r''. Use of the second include() statement was attempt to work around actual issue.
When you include urls from another directory, their path must start with the first parameter.
So when you say url(r'^$', include('home.urls')), that means: for each url in home.urls, make its path start with ^$, i.e nothing.
And when you say url(r'^mission/$', include('home.urls')), that means: for each url in home.urls, make its path start with 'mission'.
And urls are matched in order. So navigating to /mission/ matches url(r'^mission/$', include('home.urls')) and then url(r'^$', views.index, name='index'), which yields the index page.
Here's what you want:
settings.py
url(r'', include('home.urls'))
home/urls.py
url(r'^$', views.index, name='index'),
url(r'^mission/$', views.mission, name='mission'),

The URL request in Django

I remember , by default, any request to a URL that doesn’t match a URLpattern and doesn’t end with a slash will be redirected to the same URL with a trailing slash.But I occurred a problem.
the URLConf in my project :
#in urls.py file
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^cms/', include('cms.urls'))
)
#in the cms/ulrs.py
urlpatterns = patterns('cms.views',
url(r'^category/(?P<slug>[-\w]+)/$', 'category', name="cms-category"),
url(r'^search/$', 'search', { 'template' : 'cms/story_list.html'}, name="cms- search"),
)
If I typed: 127.0.0.1:8080/cms/search/ worked.
But if I type 127.0.0.1:8080/cms/search , then 404 occurred.
I just wonder why this problem existed? Can anyone give me some tips? thank you !
The easiest way to fix this would be to check the value of APPEND_SLASH in your settings.py file as suggested by John Wang. This will work only when CommonMiddleware is installed.
https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-APPEND_SLASH
Alternatively, you can add a question mark at the end of the URL Pattern in order to make the slash optional.
url(r'^search/?$', 'search', { 'template' : 'cms/story_list.html'}, name="cms- search"),
This way both '127.0.0.1:8080/cms/search/' and '127.0.0.1:8080/cms/search' will work.
It is helpful since even if we only link to one format we know people will probably visit both, either by entering the URL manually or by linking from an external source. But these are considered as two distinct URLs by search engines.
This can be tackled by doing something like the following in your URL Patterns:
url(r'^search$', redirect_to, {'url':'/search/'}),
url(r'^search/?$', 'search', { 'template' : 'cms/story_list.html'}, name="cms- search"),

Categories

Resources