Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 7

Function-Based Views in Django

Recommended resources

Hello! Welcome back.

In our last lesson, we explored the entire Django request-response cycle, giving you a high-level map of how a request travels from the browser to your application and back. We identified the view as the central component where your application's logic lives.

Today, we'll move from theory to practice. This lesson focuses on writing your first function-based views. You'll learn how to create simple Python functions that receive an HTTP request and craft an HTTP response. Given your background in Python, you'll find that a Django view is a familiar concept: it's essentially a Python function with a specific purpose and structure.

By the end of this lesson, you will be able to create your own view functions to handle web requests and return simple, dynamic content to the user.

1. The Anatomy of a View Function

At its core, a Django view is a Python callable that follows two simple rules:

  1. It must accept an HttpRequest object as its first argument.
  2. It must return an HttpResponse object.

Let's break this down.

Writing views | Django documentation

The official Django documentation provides a concise and authoritative definition of a view. Read the introductory paragraphs to solidify your understanding of a view's fundamental role and structure.

Read the sections 'Writing views' and 'A simple view'. Pay attention to the explanation of the HttpRequest and HttpResponse objects.

As the documentation explains, the request object contains all the information about the incoming request—who sent it, the HTTP method (GET, POST, etc.), headers, and any submitted data. Your view function uses this information to decide what to do.

Once your logic is complete, you package the result into an HttpResponse object. This could be simple text, a full HTML document, or even data like JSON.

Here’s a practical example based on the one from the documentation:

# This code goes inside an app's 'views.py' file.

from django.http import HttpResponse
import datetime

def current_datetime(request):
    """
    A view that returns the current date and time as an HTML string.
    """
    now = datetime.datetime.now()
    html_content = f"<html><body><h1>The current time is {now}.</h1></body></html>"
    return HttpResponse(html_content)

Notice how this function perfectly fits the definition:

  • It's a standard Python function.
  • It takes request as its first (and only) parameter.
  • It performs some logic (getting the current time).
  • It returns an HttpResponse object containing the result.

This is the fundamental pattern for all function-based views you will write.


2. Creating Your First Views

Now, let's get our hands dirty and create a couple of views in a project. By convention, views for a Django app are placed in a file named views.py inside that app's directory.

The following video provides a clear, practical walkthrough of creating this file and defining your first simple views.

Django Tutorial #3 - URLs and Views

This clip from Net Ninja's Django tutorial series demonstrates the creation of a views.py file and the definition of basic homepage and about page views.

Watch from 05:51 to 07:58. Focus on three key steps: 1. Creating the views.py file. 2. Importing the HttpResponse class. 3. Writing the simple about function that takes a request and returns a response.

Following the video's example, your views.py file for an app (let's call it pages) would look like this:

# pages/views.py

from django.http import HttpResponse

def home_view(request):
    return HttpResponse("<h1>Welcome to the Homepage!</h1>")

def about_view(request):
    return HttpResponse("<h2>About Us</h2><p>This is a simple Django site.</p>")

As you can see, we're simply returning strings containing HTML. Django wraps these strings in an HttpResponse object and sends them back to the browser, which then renders the HTML.

Test your understanding!

Inside your pages/views.py file, write a new view function called contact_view that returns an HttpResponse containing the text "Contact us at contact@example.com".

Show answer

Your function should look like this:

# pages/views.py

from django.http import HttpResponse

# ... existing views ...

def contact_view(request):
    return HttpResponse("Contact us at contact@example.com")

3. Connecting Views to URLs: A Preview

You've created views, but how does Django know when to execute them? This is handled by the URL dispatcher, which maps URL patterns to view functions. We will cover this topic in detail in our next lesson, but let's take a quick look to see how the pieces fit together.

The connection is made in a urls.py file. You define a list of path objects, where each path associates a URL route with a specific view.

Django Tutorial #3 - URLs and Views

This next clip from the same video shows how to wire up the views you just created to actual URLs. This will complete the request-response cycle for your new pages.

Watch from 07:58 to 11:22. Note how the views.py file is imported and how each URL pattern is linked to a view function. The video uses an older url() syntax; we'll use the modern path() syntax, but the concept is identical.

While the video uses url() with regular expressions, modern Django prefers path() for its simplicity. Here is what a urls.py file for our pages app would look like using the path() function:

# pages/urls.py

from django.urls import path
from . import views  # Import views from the current directory

urlpatterns = [
    path('', views.home_view, name='home'),          # For the root URL, like example.com/
    path('about/', views.about_view, name='about'),  # For example.com/about/
    path('contact/', views.contact_view, name='contact'), # For example.com/contact/
]

When a request for /about/ comes in, Django's URL router finds the matching pattern and calls views.about_view(request). Simple as that!


4. Handling Errors and Other Responses

Not all requests result in a successful page ("200 OK"). Sometimes a user might request a page that doesn't exist. A robust application needs to handle these cases gracefully. Django provides helpers for returning common HTTP errors.

The most common error is a "404 Not Found". Instead of manually crafting a HttpResponseNotFound, Django provides a more convenient way: raising an Http404 exception.

Writing views | Django documentation

The Django documentation explains how to return errors from views. This section is key for building real-world applications that can handle unexpected user input.

Read the section 'Returning errors', focusing on 'The Http404 exception'.

When you raise Http404 from within a view, Django catches it and automatically returns a properly formatted 404 error page.

Here’s a view that demonstrates this. Imagine a view that looks up a product by its ID. If the ID is invalid (e.g., doesn't exist in the database), it should return a 404.

from django.http import HttpResponse, Http404

# A simple list of product IDs for demonstration
VALID_PRODUCT_IDS = [10, 25, 30]

def product_detail(request, product_id):
    """
    A view to show a product detail page.
    The 'product_id' is captured from the URL.
    """
    if product_id not in VALID_PRODUCT_IDS:
        raise Http404("Product does not exist.")
    
    return HttpResponse(f"<h1>Displaying details for Product {product_id}</h1>")

In this example, if a user navigates to /products/25/, they will see the product page. But if they navigate to /products/99/, Django will show its standard 404 page because our view raised the Http404 exception. This is much cleaner than checking a condition and manually returning an error response.


Conclusion

In this lesson, you made the leap from understanding the request-response cycle to actively participating in it. You now have the foundational skill of creating function-based views, the workhorses of a Django application.

Key Takeaways:

  • A function-based view is a Python function that takes an HttpRequest object and returns an HttpResponse object.
  • Views are conventionally stored in a views.py file inside each Django app.
  • An HttpResponse can contain any string, including raw text or a full HTML document.
  • For common errors like "404 Not Found," you can raise the Http404 exception to let Django handle the response.
  • Views are connected to URLs via a urls.py file, which maps URL paths to specific view functions.

We only scratched the surface of connecting URLs to views. In the next lesson, we will dive deep into URL routing. You'll learn how to design clean and powerful URL schemes using path(), include(), and converters to capture dynamic values from the URL (like the product_id in our last example).