Django URLs

When someone types a web address into their browser, Django needs to figure out which view to run. This decision is handled by the URL Configuration, also called URL routing. It is the GPS of your Django website — it maps every address to a destination.

What is URL Routing?

URL routing is the process of matching a web address (URL) typed by the user to a specific view function in your Django project. Django looks at the URL and says "Ah, for this address, I should run this function."

Example: Imagine a post office. Letters (requests) arrive with different addresses. The sorter (URL router) looks at each address and sends the letter to the correct department. /home goes to the Home department, /contact goes to the Contact department.

Where is URL Configuration Stored?

Django has two levels of URL files:

  • Project-level urls.py — Located inside the project settings folder (e.g., myschool/urls.py). This is the main entry point for all URLs.
  • App-level urls.py — Located inside each app folder (e.g., school/urls.py). You create this file manually. It holds URLs specific to that app.
Example: The project-level urls.py is like a building's main reception. It receives all visitors and directs them to the correct floor. Each app's urls.py is like the receptionist on that floor who directs visitors to the correct office.

The path() Function

Django uses the path() function to define URL patterns. Each path() entry connects a URL address to a view function.


path('URL/', view_function, name='url-name')
  • URL/ — The address pattern (what the user types in the browser).
  • view_function — The view that runs when this URL is visited.
  • name — An optional short nickname for this URL so you can refer to it by name in your templates instead of typing the full URL.

Project-Level URLs Setup

Open myschool/urls.py. By default it looks like this:


from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]

You can add your app views directly here, but the best practice is to create a separate urls.py inside each app and include it here using include().

Creating App-Level URLs

Inside your school app folder, create a new file called urls.py manually:


school/
└── urls.py      <-- Create this file yourself

Now add your app URLs inside it:


from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('about/', views.about, name='about'),
    path('contact/', views.contact, name='contact'),
]

The . in from . import views means "import views from the current folder (school app)".

Including App URLs in Project URLs

Now go back to myschool/urls.py and include the school app's URLs using include():


from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('school.urls')),    # <-- Include school app URLs
]
Example: The project-level urls.py is like a company switchboard. When a call (request) comes in, the switchboard connects it to the right department's (app's) internal directory (include). The department then handles the call from there.

URL Patterns with Dynamic Values

Sometimes a URL needs to carry a value — like a student ID or a product name. You can capture these dynamic values using URL parameters:


# In school/urls.py
path('student/<int:student_id>/', views.student_detail, name='student-detail'),

In views.py, the view receives the captured value as a parameter:


def student_detail(request, student_id):
    return HttpResponse(f"Showing details for Student ID: {student_id}")

Now visiting http://127.0.0.1:8000/student/5/ will show "Showing details for Student ID: 5".

Common URL Parameter Types

  • <int:name> — Captures a whole number. Example: /student/3/
  • <str:name> — Captures any text (no slashes). Example: /category/science/
  • <slug:name> — Captures text with hyphens. Example: /post/my-first-blog/
Example: Think of a parcel delivery service. The URL /parcel/1024/ is like a tracking number. The view function is the tracking system that looks up parcel number 1024 and tells you where it is.

The name Parameter and reverse URLs

Giving a URL a name is very useful. Instead of hardcoding the URL address everywhere in your templates, you use the name. If the URL address ever changes, you only update it in one place.


# In urls.py
path('contact/', views.contact, name='contact-page'),

<!-- In a template, use the name instead of the full URL -->
<a href="{% url 'contact-page' %}">Contact Us</a>
Example: Instead of remembering a person's full home address, you save their name in your contacts. Even if they move to a new house (URL changes), you just update the address once and all your messages still find them.

Full URL Flow — How it All Works Together


User types: http://127.0.0.1:8000/about/
        |
        v
myschool/urls.py  -->  finds: include('school.urls')
        |
        v
school/urls.py  -->  finds: path('about/', views.about)
        |
        v
school/views.py  -->  runs: def about(request)
        |
        v
Browser shows the About page

Quick Recap


# school/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='home'),
    path('about/', views.about, name='about'),
    path('student/<int:id>/', views.student_detail, name='student-detail'),
]

# myschool/urls.py
from django.urls import path, include
urlpatterns = [
    path('', include('school.urls')),
]

Leave a Comment

Your email address will not be published. Required fields are marked *