Django from Basics to Production · Django Fundamentals

Your First Django View

Map URLs to views, return JSON and HTML, and call them with Django's test client, in a single-file Django project.

Create a free account to save this page, take notes and track your progress. Sign in

What you'll build

Two views (a JSON endpoint and an HTML page) wired to URLs, called with Django's test client, which sends requests through the full Django stack without a server. Each example in this course is a complete single-file Django project: the first lines call settings.configure() and register the file as an app named shop, which a real project gets from settings.py and INSTALLED_APPS, and the rest would live in urls.py, views.py and models.py.

The idea

  • A view is a function (or class) that takes an HttpRequest and returns an HttpResponse.
  • URL patterns (path("books/<int:pk>/", view)) map paths to views; converters like <int:pk> validate and convert parameters.
  • JsonResponse serialises dictionaries; HttpResponse returns text or HTML.
  • django.test.Client makes requests in-process and is the basis of Django tests.

The code

Views, URLs and the test client
import sys, types
import django
from django.conf import settings

sys.modules["shop"] = types.ModuleType("shop")       # lets this single file act as the "shop" app
sys.modules["shop"].__file__ = __file__
settings.configure(
    SECRET_KEY="dev-only", DEBUG=False, ALLOWED_HOSTS=["testserver"], ROOT_URLCONF=__name__,
    DATABASES={"default": {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"}},
    INSTALLED_APPS=["django.contrib.contenttypes", "django.contrib.auth", "shop"],
)
django.setup()

from django.http import Http404, HttpResponse, JsonResponse
from django.urls import path

BOOKS = {1: "Dune", 2: "Emma"}

def book_detail(request, pk):
    if pk not in BOOKS:
        raise Http404("no such book")
    return JsonResponse({"id": pk, "title": BOOKS[pk]})

def home(request):
    name = request.GET.get("name", "reader")
    return HttpResponse(f"<h1>Hello, {name}</h1>")

urlpatterns = [path("", home), path("books/<int:pk>/", book_detail)]

from django.test import Client

client = Client()
for url in ["/books/2/", "/books/9/", "/books/abc/", "/?name=Ana"]:
    r = client.get(url)
    body = r.content.decode()[:60] if r.status_code == 200 else "(Django's 404 page)"
    print(url, r.status_code, r.headers["Content-Type"].split(";")[0], body)

Output

/books/2/ 200 application/json {"id": 2, "title": "Emma"}
/books/9/ 404 text/html (Django's 404 page)
/books/abc/ 404 text/html (Django's 404 page)
/?name=Ana 200 text/html <h1>Hello, Ana</h1>

Run this on your computer — see “Get Started” for setup.

Common mistakes

  • Building HTML with f-strings and user input (as in this tiny example's name): use templates, which escape automatically (see the templates lesson).
  • DEBUG = True in production, which exposes settings and code in error pages.
  • Forgetting ALLOWED_HOSTS, so every request gets a 400 in production.

Key points

  • Views take a request and return a response; URLs map paths to views.
  • Path converters validate parameters (/books/abc/ never reaches the view).
  • The test client exercises the full stack without a server.

Further reading: Writing views · URL dispatcher

Practice questions

What does the <int:pk> path converter do?

Answer

It matches only digits and passes the value to the view as an int; non-numeric paths don't match the pattern and get a 404.

Why must DEBUG be False in production?

Answer

Debug error pages reveal settings, code, SQL and environment details, and Django keeps extra debugging data in memory.

What does Django's test Client do?

Answer

It sends requests through URL routing, middleware and views in-process, returning the response for assertions, without running a server.

Open in the app to mark lessons complete, take notes and track your progress.

Was this page helpful?