Python Django Views

Last Updated: 30 Sep, 2026

What Are Views in Django? Function-Based, Class-Based and Generic Views

Views in Django are Python functions or classes that receive a web request and return a web response: an HTML page, a redirect, a 404 error, JSON or a file. A view sits between your URLs and your data. It reads the request, fetches or saves data through models, and passes the result to a template or serializer.

Every view follows one contract: it takes an HttpRequest as its first argument and must return an HttpResponse (or raise an exception such as Http404). Everything else, such as which template to use or what to query, is up to you.

Function-Based Views vs Class-Based Views

Django supports two styles. Function-based views (FBVs) are plain Python functions, so the logic is explicit and easy to follow. Class-based views (CBVs) are classes that handle each HTTP method in its own method (get(), post()), and they can be extended through inheritance and mixins.

Function-based view Class-based view
Looks like def post_list(request): … class PostList(ListView): …
Wired in urls.py as views.post_list views.PostList.as_view()
Handling GET vs POST if request.method == “POST”: Separate get() and post() methods
Reuse Decorators such as @login_required Inheritance and mixins such as LoginRequiredMixin
Best for One-off or unusual logic, learning Standard list/detail/create/update/delete pages

 

What Are Generic Views in Django?

Generic views are ready-made class-based views in django.views.generic that implement common page patterns. You configure them with attributes like model, template_name, fields and success_url instead of writing the query and rendering code yourself.

Generic view What it does Default template
TemplateView Renders a template, optionally with extra context Set with template_name
ListView Lists objects of a model, with optional pagination <app>/<model>_list.html
DetailView Shows one object found by pk or slug <app>/<model>_detail.html
CreateView Displays and processes a form that creates an object <app>/<model>_form.html
UpdateView Displays and processes a form that edits an object <app>/<model>_form.html
DeleteView Confirms and deletes an object <app>/<model>_confirm_delete.html
FormView / RedirectView Processes a non-model form / redirects to another URL Set with template_name / none

 

How to Get Data from the Database in a Django View

Inside a view you query a model through its manager, Model.objects, then pass the results to a template in the context dictionary. Use get_object_or_404() when fetching a single row, so a missing record returns a proper 404 page instead of a server error.

from django.shortcuts import render, get_object_or_404

from .models import Post

 

def post_list(request):

posts = Post.objects.filter(published=True).order_by(“-created_at”)

return render(request, “blog/post_list.html”, {“posts”: posts})

 

def post_detail(request, slug):

post = get_object_or_404(Post, slug=slug, published=True)

return render(request, “blog/post_detail.html”, {“post”: post})

 

For related data, add select_related(“author”) (ForeignKey) or prefetch_related(“tags”) (many-to-many) to the query so the template doesn’t trigger one extra query per row.

How to Import Views in Django (urls.py)

Views are connected to URLs in a URLconf. Inside an app, import the app’s views module with a relative import and reference each view in path(). Then include the app’s URLs from the project’s root urls.py.

# blog/urls.py

from django.urls import path

from . import views

 

app_name = “blog”

urlpatterns = [

path(“”, views.post_list, name=”post_list”),

path(“<slug:slug>/”, views.post_detail, name=”post_detail”),

]

 

# mysite/urls.py

from django.urls import include, path

urlpatterns = [

path(“blog/”, include(“blog.urls”)),

]

 

Prefer from . import views over from .views import *. It keeps names unambiguous and makes it obvious where each view comes from.

How to Create a View in Django That Fetches Data from the Database

You will build a blog list page and a detail page: first as function-based views, then by converting the list page to a generic ListView. It takes 7 steps and about 25 minutes, and assumes you already have a project with a blog app.

Prerequisites

  • A Django project with an app named blogadded to INSTALLED_APPS (see the Django topic’s tutorial).
  • Migrations applied (python manage.py migrate) and a superuser created.
  • Basic Python classes and functions.

Steps

Step 1: Define a model

Add a Post model to blog/models.py, then run makemigrations and migrate.

from django.db import models

 

class Post(models.Model):

title = models.CharField(max_length=200)

slug = models.SlugField(unique=True)

body = models.TextField()

published = models.BooleanField(default=True)

created_at = models.DateTimeField(auto_now_add=True)

 

def __str__(self):

return self.title

 

Step 2: Add sample data through the admin

Register the model in blog/admin.py with admin.site.register(Post), open /admin/ and create two or three posts.

 

.

Step 3: Write a function-based list view

In blog/views.py, query published posts and render them.

from django.shortcuts import render, get_object_or_404

from .models import Post

 

def post_list(request):

posts = Post.objects.filter(published=True).order_by(“-created_at”)

return render(request, “blog/post_list.html”, {“posts”: posts})

 

Step 4: Write a detail view

Fetch one post by its slug; a wrong slug returns a 404.

def post_detail(request, slug):

post = get_object_or_404(Post, slug=slug, published=True)

return render(request, “blog/post_detail.html”, {“post”: post})

 

Step 5: Import the views and map URLs

Create blog/urls.py with from . import views and two path() entries (shown above in “How to Import Views”), then add path(“blog/”, include(“blog.urls”)) to the project URLconf.

Step 6: Create minimal templates

Create blog/templates/blog/post_list.html that loops over posts and links to each post, and post_detail.html that shows {{ post.title }} and {{ post.body|linebreaks }}.

{% for post in posts %}

<a href=”{% url ‘blog:post_detail’ post.slug %}”>{{ post.title }}</a>

{% empty %}

<p>No posts yet.</p>

{% endfor %}

 

django_views_step

Figure: The unstyled post list rendered by the post_list view at /blog/.

Step 7: Convert the list page to a generic ListView

Replace post_list with a class-based view and update the URL to views.PostList.as_view(). The template keeps working because context_object_name is set to posts.

from django.views.generic import ListView

 

class PostList(ListView):

queryset = Post.objects.filter(published=True).order_by(“-created_at”)

template_name = “blog/post_list.html”

context_object_name = “posts”

paginate_by = 10