Django Views: Creating and Using Views the Right Way
Last updated 1 month, 3 weeks ago | 123 views 75 5

In Django, views are the heart of your application’s logic. They process HTTP requests, interact with models, and return HTTP responses — often rendering templates or JSON data.
This article walks you through everything you need to know about creating and managing views in Django, including function-based views (FBVs), class-based views (CBVs), and when to use each.
What Is a View in Django?
A view in Django is a Python function or class that:
-
Accepts a web request
-
Processes data (optional)
-
Returns a web response (HTML, JSON, redirect, etc.)
Views are the bridge between URLs, models, and templates.
Step 1: Set Up a Django Project and App
Before you create views, ensure you have a project and app:
django-admin startproject mysite
cd mysite
python manage.py startapp blog
Register the app in settings.py
:
INSTALLED_APPS = [
...
'blog',
]
Step 2: Create a Function-Based View (FBV)
FBVs are simple Python functions.
Example:
# blog/views.py
from django.http import HttpResponse
def home(request):
return HttpResponse("Welcome to the Blog!")
Hook it to a URL:
Create blog/urls.py
:
from django.urls import path
from . import views
urlpatterns = [
path('', views.home, name='home'),
]
Include it in your main mysite/urls.py
:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('blog.urls')),
]
Visit http://127.0.0.1:8000/
to see the message.
Step 3: Return an HTML Template
Instead of plain text, return a rendered template.
Create a template:
mkdir -p blog/templates/blog
<!-- blog/templates/blog/home.html -->
<!DOCTYPE html>
<html>
<head>
<title>Blog Home</title>
</head>
<body>
<h1>Hello from the Blog!</h1>
</body>
</html>
Modify the view:
from django.shortcuts import render
def home(request):
return render(request, 'blog/home.html')
Step 4: Class-Based Views (CBVs)
CBVs are Python classes that encapsulate logic in reusable components. Django provides several generic CBVs like ListView
, DetailView
, etc.
Simple CBV Example:
from django.views import View
from django.http import HttpResponse
class AboutView(View):
def get(self, request):
return HttpResponse("This is the About page.")
Hook to URL:
from .views import AboutView
urlpatterns = [
path('', views.home, name='home'),
path('about/', AboutView.as_view(), name='about'),
]
Step 5: Using Generic Class-Based Views
Generic CBVs reduce boilerplate.
Example with ListView
:
from django.views.generic import ListView
from .models import Post
class PostListView(ListView):
model = Post
template_name = 'blog/post_list.html'
context_object_name = 'posts'
URL:
path('posts/', PostListView.as_view(), name='post_list'),
Template:
<!-- blog/templates/blog/post_list.html -->
<h1>All Posts</h1>
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
FBVs vs CBVs
Feature | Function-Based Views (FBV) | Class-Based Views (CBV) |
---|---|---|
Simplicity | ✅ Simple for small views | ❌ Verbose for small tasks |
Reusability | ❌ Needs decorators | ✅ Inheritance, mixins |
Readability | ✅ Obvious logic flow | ❌ Harder for beginners |
Extensibility | ❌ Requires manual logic | ✅ Easy to extend via OOP |
Recommendation:
-
Use FBVs for small/simple views
-
Use CBVs for larger, reusable views
Step 6: Handling POST Requests
Views can also handle POST data (e.g., from forms).
Example FBV:
def contact(request):
if request.method == 'POST':
name = request.POST.get('name')
return HttpResponse(f"Thanks, {name}!")
return render(request, 'blog/contact.html')
Template:
<!-- blog/templates/blog/contact.html -->
<form method="POST">
{% csrf_token %}
<input type="text" name="name" placeholder="Your name" required>
<button type="submit">Send</button>
</form>
Step 7: Cleaning Up with Django Forms (Optional)
For better structure, use Django's forms
module.
# blog/forms.py
from django import forms
class ContactForm(forms.Form):
name = forms.CharField(max_length=100)
# blog/views.py
from .forms import ContactForm
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
return HttpResponse("Thanks, " + form.cleaned_data['name'])
else:
form = ContactForm()
return render(request, 'blog/contact.html', {'form': form})
✅ Best Practices for Django Views
-
✅ Keep views short and focused
-
✅ Use CBVs for reusable patterns
-
✅ Validate POST data using Django forms
-
✅ Use
render()
instead of manualHttpResponse
for templates -
✅ Avoid business logic in views – use models or services instead
⚠️ Common Pitfalls
Mistake | Fix |
---|---|
❌ Not returning an HttpResponse |
✅ Always return HttpResponse , render() , or redirect |
❌ Forgetting .as_view() in CBVs |
✅ Use AboutView.as_view() not AboutView |
❌ Mixing GET/POST logic without checks | ✅ Use request.method to branch logic |
❌ Using render() without proper template path |
✅ Match template directory structure and settings |
❌ Missing CSRF token in forms | ✅ Include {% csrf_token %} in forms |
Conclusion
Django views are central to how your application responds to user interactions. Whether you use FBVs for simplicity or CBVs for structure, Django provides the flexibility to organize your views efficiently.
With clean, well-structured views, your project becomes easier to scale, debug, and maintain.
Want to go further?
-
Learn how to return JSON responses for APIs
-
Use decorators like
@login_required
to protect views -
Explore mixins in CBVs for better reusability