I finished https://docs.djangoproject.com/en/1.9/intro/tutorial01/
The intended behaviour works. My polls index is showing. But there is one unintended consequence that I don't understand. When I go to localhost:8000
I get a page not found. Why?
This is my mysite/mysite/urls.py
as the tutorial explained.
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^polls/', include('polls.urls')),
url(r'^admin/', admin.site.urls),
]
The server says:
Not Found: /
[11/Feb/2016 04:25:46] "GET / HTTP/1.1" 404 2010
When I delete the polls line, the 404 disappears. I.e.:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
Now the server says:
Not Found: /
[11/Feb/2016 04:24:23] "GET / HTTP/1.1" 200 1767
So I guess it is some default quirk but I still don't fully know if I am making a mistake or if this is defined behaviour. My other code is the same as in the code snippets of the tutorial.
The tutorial does not define what will happen when you go to your site root, it only deals with the polls
app. You have to add a url mapping if you want to see something when you browse to http://localhost:8080/
.
As a simple example, try making the following changes in your mysite/urls.py
:
from polls import views
urlpatterns = [
url(r'^$', views.index, name='site_index'),
...
]
From now on you should see the index view of polls
app when you browse to your site root.
Interesting observation! Never noticed that before.
When you access a URL, Django tries to match it with the all the defined patterns (in the order of definition). For the first pattern it matches, the corresponding view will be called.
But if there is no URL pattern defined, then django will print Not found: {url}
that you see in the runserver
shell. And it will try to raise 404 exception, as expected.
But in the debug
mode, it does a bit extra.
Let's examine this function in django/views/debug.py
:
def technical_404_response(request, exception):
# some extra code here
if (not tried # empty URLconf
or (request.path == '/'
and len(tried) == 1 # default URLconf
and len(tried[0]) == 1
and getattr(tried[0][0], 'app_name', '') == getattr(tried[0][0], 'namespace', '') == 'admin')):
return default_urlconf(request)
# more extra code here
What Django tries to do here is check how many URL patterns it tried. If specific conditions meet, it will try to return through the default_urlconf
.
These specific conditions are:
admin
appSo what we learn from here that if no URL pattern is defined, then Django will always call the default_urlconf
. Try deleting the admin
URLs also, and then access any random URL. You will always get something like this:
Not Found: /random/url/
[11/Feb/2016 04:24:23] "GET /random/url/ HTTP/1.1" 200 1767
Now let us look at the default_urlconf
code:
def default_urlconf(request):
"Create an empty URLconf 404 error response."
t = DEBUG_ENGINE.from_string(DEFAULT_URLCONF_TEMPLATE)
c = Context({
"title": _("Welcome to Django"),
"heading": _("It worked!"),
"subheading": _("Congratulations on your first Django-powered page."),
"instructions": _("Of course, you haven't actually done any work yet. "
"Next, start your first app by running <code>python manage.py startapp [app_label]</code>."),
"explanation": _("You're seeing this message because you have <code>DEBUG = True</code> in your "
"Django settings file and you haven't configured any URLs. Get to work!"),
})
return HttpResponse(t.render(c), content_type='text/html')
(It returns a proper HttpResponse
=> 200 HTTP code)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With