Reputation: 103
I've encountered a one nasty bug in my code while developing a personal blog in Django. Basically, I've changed my urls.py file by adding a couple of rules to make certain views accessible.
urls.py
from django.conf.urls import include, url
from django.contrib import admin
from blog import views
urlpatterns = [
# Examples:
# url(r'^$', 'blogas.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^$', views.index, name='index'),
url(r'^(?P<slug>\w+)', views.view_post, name='view_blog_post'),
url(r'^about/$', views.about, name='about'),
url(r'^posts/$', views.posts, name='posts'),
]
Everything seems to be working except when I try access http://127.0.0.1:8000/
about or /posts, Django throws out a 404 error. What is the reason of this? I've defined both rules but the system seems not to recognize the pattern - maybe I've mispelled something? Maybe I know nothing about url formatting (could be, it's my first time doing this stuff)?
A big thanks from a newbie programmer to everyone who finds the bug :)
Upvotes: 1
Views: 1142
Reputation: 42748
The url-patterns are processed from top to bottom. Your third pattern ^(?P<slug>\w+)
consumes everything, so about
and posts
is never reached.
An example: Django wants to find the view for the url about/
. The patterns ^admin/
and ^$
do not match. But ^(?P<slug>\w+)
does, because about
starts with letters or numbers (the character sets contained in \w
)
>>> import re
>>> re.search('^(?P<slug>\w+)', 'about/')
<_sre.SRE_Match object at 0x10b5b7be8>
So Django found a match, callBs views.view_post
and finishes the request. That means, the more specific rule must come first. Better: avoid ambiguity.
Upvotes: 5
Reputation: 699
You have to change position of url(r'^(?P<slug>\w+)', views.view_post, name='view_blog_post'),
.
urlpatterns = [
# Examples:
# url(r'^$', 'blogas.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^$', views.index, name='index'),
url(r'^about/$', views.about, name='about'),
url(r'^posts/$', views.posts, name='posts'),
url(r'^(?P<slug>\w+)', views.view_post, name='view_blog_post'),
]
urlpatterns is list and order of urls is important.
Upvotes: 2