Views & URLs
In Django, a view is a Python function (or class) that takes a web request and returns a web response, and a URL configuration (urls.py) is the routing table that maps each URL path to the view that should handle it.
Learn Views & URLs in our free Django course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Django course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
In this lesson you'll write your first view that returns an HttpResponse, wire it up in urls.py with the path() function, and learn how to capture values straight from the URL and pass them into your view.
A view is the simplest building block in Django. It is a plain Python function that accepts a request object as its first argument and returns a response . The most basic response is an HttpResponse containing some text or HTML.
Views live in a file called views.py inside your app. Here is a minimal one:
The function receives the incoming request , builds an HttpResponse , and returns it. Django sends that response straight back to the browser. Every view must return a response object — returning nothing is an error.
A view does nothing on its own — Django needs to know which URL should trigger it. That mapping lives in urls.py , your project's routing table. You build it with the path() function from django.urls .
The path() function takes three useful parts:
So path('about/', views.about, name='about') reads as: "when a browser requests /about/ , run the about view, and call this route 'about' ."
Real apps need dynamic URLs — a blog post page like /posts/5/ shouldn't need a separate view for every post. Django captures part of the URL using a path converter written in angle brackets, then passes the captured value into your view as an argument.
The converter has two parts: int says "match a whole number," and post_id is the name Django uses when it passes the value to your view. Visiting /posts/5/ calls post_detail(request, post_id=5) .
Fill in the blank so the view returns a response that greets the captured username .
❌ The view didn't return an HttpResponse object
Your view ran but forgot to return a response, so it returned None .
✅ Fix: make sure every path through the view ends with return HttpResponse(...) or return render(...) .
❌ Page not found (404) for a URL you just wrote
The path isn't registered in urlpatterns , or the route string doesn't match (a missing trailing slash is a common cause).
✅ Fix: add the path(...) entry to urls.py and check the route string matches exactly.
❌ TypeError: post_detail() got an unexpected keyword argument
The converter name in the URL doesn't match the argument name in your view.
✅ Fix: make and the view's post_id parameter use the exact same name.
Build a mini routing table that maps two paths to two views, then resolve a couple of requests through it — just like Django does.
Lesson 3 complete — your URLs now reach your views!
You can write a function-based view that returns an HttpResponse, register it in urls.py with the path() function, name your routes, and capture dynamic values from the URL with path converters like .
🚀 Up next: Templates — return real HTML pages with Django's templating engine instead of plain strings.
Practice quiz
What is a function-based view in Django?
- A routing rule in urls.py
- A Python function that takes a request and returns a response
- A template that renders HTML
- A database model class
Answer: A Python function that takes a request and returns a response. A view is a function that receives a request object and returns a response such as an HttpResponse.
What is the first argument every function-based view receives?
- The response object
- The URL string
- The context dictionary
- The request object
Answer: The request object. A view's first parameter is always the incoming request object.
Which class builds a basic text or HTML response?
- HttpResponse
- HttpRequest
- JsonRequest
- TemplateResponse
Answer: HttpResponse. HttpResponse('...') from django.http builds a simple text/HTML response.
What happens if a view returns None instead of a response?
- Django returns a blank page
- The previous response is reused
- Django raises 'The view didn't return an HttpResponse object.'
- Django returns a 200 with empty body
Answer: Django raises 'The view didn't return an HttpResponse object.'. Every view must return a response object; returning None raises that error.
Which function maps a URL to a view in urls.py?
- route()
- path()
- url_map()
- connect()
Answer: path(). path() from django.urls maps a route string to a view, with an optional name.
What does name='about' in a path() call let you do?
- Reverse the URL elsewhere with {% url 'about' %} or reverse('about')
- Cache the view's output
- Restrict the view to GET requests
- Automatically create a template named about.html
Answer: Reverse the URL elsewhere with {% url 'about' %} or reverse('about'). Naming a URL lets you build it by name so changing the path later does not break links.
Which path converter matches a whole number from the URL?
- <str:id>
- <slug:id>
- <num:id>
- <int:post_id>
Answer: <int:post_id>. <int:post_id> matches a whole number and passes it to the view as post_id.
Given path('posts/<int:post_id>/', ...), how is the view called for /posts/5/?
- post_detail(5)
- post_detail(request)
- post_detail(request, post_id=5)
- post_detail(post_id=5, request)
Answer: post_detail(request, post_id=5). The captured value is passed as a keyword argument: post_detail(request, post_id=5).
Which converter matches a hyphenated label like my-first-post?
- <slug:slug>
- <int:slug>
- <str:slug>
- <path:slug>
Answer: <slug:slug>. The slug converter matches hyphenated, lowercase labels like my-first-post.
A TypeError about an unexpected keyword argument from a captured value usually means:
- The view forgot to import HttpResponse
- The URL route has a trailing slash
- The converter name does not match the view's parameter name
- The path is not in urlpatterns
Answer: The converter name does not match the view's parameter name. The name in <int:post_id> must match the view's parameter name, or Django raises a TypeError.