Last Updated on July 11, 2026 by Rajeev Bagra
One of the most important jobs in any web application is deciding what should happen when a user visits a particular URL.
For example:
/
should display the homepage, while:
/about/
might display information about your website.
But how does Django know which page to show?
The answer lies in URL routing.
In this lesson, we’ll learn how Django uses urls.py, the path() function, URL parameters, and include() to send requests to the correct view.
What Is URL Routing?
Imagine a receptionist working in a large office.
Whenever a visitor arrives, the receptionist asks:
“Which department do you want to visit?”
Depending on the answer, the receptionist sends the visitor to the correct office.
Django’s URL routing works in exactly the same way.
Browser
│
▼
urls.py
│
▼
Correct View
│
▼
Response
The browser sends a request.
The URL dispatcher examines the URL.
If it finds a matching pattern, Django calls the corresponding view.
The Project-Level urls.py
Every Django project contains a file called:
wiki/
urls.py
A simple example looks like this:
from django.contrib import admin
from django.urls import path
urlpatterns = [
path("admin/", admin.site.urls),
]
Notice the list named:
urlpatterns
This list contains all the URL patterns Django should recognize.
Understanding path()
The syntax is:
path(route, view)
The first argument is the URL.
The second argument is the function that should execute.
Example:
path("", views.index)
Here:
Route:
""
means the homepage.
If the user visits:
http://127.0.0.1:8000/
Django executes:
views.index(request)
Adding Multiple URLs
Example:
urlpatterns = [
path("", views.home),
path("about/", views.about),
path("contact/", views.contact),
]
Now Django knows:
/
↓
home()
/about/
↓
about()
/contact/
↓
contact()
Each URL is connected to a different view.
How Django Matches URLs
Suppose the user visits:
/about/
Django checks each URL pattern from top to bottom.
urlpatterns = [
path("", views.home),
path("about/", views.about),
path("contact/", views.contact),
]
Step 1:
/about/
Does it match:
""
No.
Step 2:
Does it match:
"about/"
Yes.
Django immediately executes:
views.about(request)
Once a match is found, Django stops searching.
What Happens If No URL Matches?
Suppose the user visits:
/products/
but your project only has:
urlpatterns = [
path("", views.home),
path("about/", views.about),
]
No pattern matches.
Django returns:
404 Page Not Found
Connecting URLs to Views
Suppose:
urlpatterns = [
path("hello/", views.hello),
]
Inside:
views.py
we have:
from django.http import HttpResponse
def hello(request):
return HttpResponse("Hello Django!")
Now visiting:
/hello/
returns:
Hello Django!
Dynamic URLs with Parameters
Static URLs are useful, but many websites need dynamic pages.
Examples:
/wiki/Python
/wiki/HTML
/wiki/Django
Instead of creating hundreds of URL patterns, Django lets us capture values.
Example:
path("wiki/<str:title>/", views.entry)
Here:
<str:title>
means:
Capture a string and store it in a variable called:
title
How URL Parameters Work
Suppose the user visits:
/wiki/Python/
Django extracts:
title = "Python"
and calls:
views.entry(request, title)
which becomes:
views.entry(request, "Python")
Inside the view:
def entry(request, title):
return HttpResponse(title)
Output:
Python
Different Parameter Types
Django supports several converters.
String:
path("user/<str:name>/", views.user)
Integer:
path("article/<int:id>/", views.article)
Slug:
path("post/<slug:slug>/", views.post)
UUID:
path("order/<uuid:id>/", views.order)
Path (captures entire paths):
path("files/<path:filename>/", views.file)
Example with Integers
URL:
path("student/<int:id>/", views.student)
User visits:
/student/25/
Django executes:
views.student(request, 25)
Notice that:
25
is automatically converted into an integer.
What Is include()?
As projects grow, putting every URL into one file becomes difficult.
Instead, Django allows apps to manage their own URLs.
Project structure:
wiki/
│
├── urls.py
│
└── encyclopedia/
├── urls.py
└── views.py
Project-level URLs:
from django.urls import include, path
urlpatterns = [
path("wiki/", include("encyclopedia.urls")),
]
Now every URL beginning with:
/wiki/
is handled by:
encyclopedia/urls.py
App-Level URLs
Inside:
encyclopedia/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index),
path("<str:title>/", views.entry),
]
Now the URL flow becomes:
/wiki/
│
▼
Project urls.py
│
▼
include()
│
▼
App urls.py
│
▼
Correct View
This keeps large projects organized.
Real Example
Project URLs:
urlpatterns = [
path("wiki/", include("encyclopedia.urls")),
]
App URLs:
urlpatterns = [
path("", views.index),
path("<str:title>/", views.entry),
]
User visits:
/wiki/Python/
Django follows this path:
Browser
│
▼
Project urls.py
│
▼
include()
│
▼
App urls.py
│
▼
title = "Python"
│
▼
views.entry(request, "Python")
Complete Request Flow
Browser
│
▼
Project urls.py
│
▼
include()
│
▼
App urls.py
│
▼
URL Match
│
▼
View Function
│
▼
Template
│
▼
HTML Response
│
▼
Browser
Key Takeaways
✅ urls.py tells Django which view should handle each URL.
✅ path() connects a URL pattern to a view function.
✅ Django checks URL patterns from top to bottom until it finds a match.
✅ If no pattern matches, Django returns a 404 Page Not Found error.
✅ URL parameters like <str:title> and <int:id> allow dynamic pages.
✅ include() lets each app maintain its own urls.py, making large projects easier to organize.
Next Lesson
Understanding Django Views: Requests, Responses, render(), and HttpResponse
In the next lesson, we’ll explore what happens after a URL matches a view. You’ll learn how Django processes a request, the difference between HttpResponse() and render(), how data is passed to templates, and why views are often called the “brains” of a Django application.
Discover more from Progaiz.com
Subscribe to get the latest posts sent to your email.


Leave a Reply