Lukas Valatka
Lukas Valatka

Reputation: 103

Django urls.py bug - some patterns not working

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

Answers (2)

Daniel
Daniel

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

Sławek Kabik
Sławek Kabik

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

Related Questions