Django Views
Handling requests and returning responses
👁️ What are Django Views?
Views are Python functions or classes that receive web requests and return web responses. They contain the logic for processing user input, interacting with models, and rendering templates to display content.
def home(request):
return render(request, 'home.html')
Types of Views
Function Views
Simple Python functions
def my_view(request):
return HttpResponse('Hello')
Class Views
Object-oriented approach
class MyView(View):
def get(self, request):
Generic Views
Pre-built common patterns
class PostList(ListView):
model = Post
API Views
Return JSON responses
return JsonResponse(data)
🔹 Function-Based Views (FBV)
Function-based views are simple Python functions that take a request object and return a response. They're straightforward and perfect for beginners.
🔸 Basic Function View
# blog/views.py
from django.shortcuts import render
from django.http import HttpResponse
def home(request):
return HttpResponse("Welcome to my blog!")
def about(request):
return render(request, 'blog/about.html')
def contact(request):
context = {
'email': '[email protected]',
'phone': '123-456-7890'
}
return render(request, 'blog/contact.html', context)
Output:
Welcome to my blog!
🔹 Views with Database Queries
Views commonly retrieve data from models to display on web pages. Use Django's ORM to query the database efficiently.
# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_list(request):
# Get all posts
posts = Post.objects.all().order_by('-published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
def post_detail(request, pk):
# Get single post or 404
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {'post': post})
def recent_posts(request):
# Filter posts
posts = Post.objects.filter(published_date__year=2024)[:5]
return render(request, 'blog/recent.html', {'posts': posts})
🔹 Handling Form Submissions
Views process form data submitted by users. Check the request method to handle GET and POST requests differently.
# blog/views.py
from django.shortcuts import render, redirect
from .models import Post
def create_post(request):
if request.method == 'POST':
# Process form data
title = request.POST.get('title')
content = request.POST.get('content')
# Create new post
Post.objects.create(title=title, content=content)
# Redirect after successful submission
return redirect('post_list')
# Display empty form for GET request
return render(request, 'blog/create_post.html')
<!-- templates/blog/create_post.html -->
<form method="post">
{% csrf_token %}
<input type="text" name="title" placeholder="Title" required>
<textarea name="content" placeholder="Content" required></textarea>
<button type="submit">Create Post</button>
</form>
🔹 Class-Based Views (CBV)
Class-based views organize code using object-oriented programming. They provide reusable components and handle common patterns efficiently.
🔸 Basic Class View
# blog/views.py
from django.views import View
from django.shortcuts import render
from django.http import HttpResponse
class HomeView(View):
def get(self, request):
return render(request, 'blog/home.html')
def post(self, request):
# Handle POST request
return HttpResponse("Form submitted!")
# blog/urls.py
from django.urls import path
from .views import HomeView
urlpatterns = [
path('', HomeView.as_view(), name='home'),
]
🔹 Generic Class-Based Views
Django provides generic views for common patterns like listing objects, displaying details, creating, updating, and deleting records.
🔸 ListView - Display Multiple Objects
# blog/views.py
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'
ordering = ['-published_date']
paginate_by = 10
🔸 DetailView - Display Single Object
from django.views.generic import DetailView
class PostDetailView(DetailView):
model = Post
template_name = 'blog/post_detail.html'
context_object_name = 'post'
🔸 CreateView - Create New Object
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content']
template_name = 'blog/post_form.html'
success_url = reverse_lazy('post_list')
🔹 Passing Context to Templates
Views pass data to templates using context dictionaries. Templates can then access this data to display dynamic content.
# blog/views.py
from django.shortcuts import render
from .models import Post, Author
def dashboard(request):
context = {
'total_posts': Post.objects.count(),
'recent_posts': Post.objects.all()[:5],
'authors': Author.objects.all(),
'site_name': 'My Blog',
}
return render(request, 'blog/dashboard.html', context)
<!-- templates/blog/dashboard.html -->
<h1>{{ site_name }} Dashboard</h1>
<p>Total Posts: {{ total_posts }}</p>
<h2>Recent Posts</h2>
{% for post in recent_posts %}
<p>{{ post.title }}</p>
{% endfor %}
🔹 HTTP Response Types
Django views can return different types of responses depending on your needs:
from django.http import HttpResponse, JsonResponse, HttpResponseRedirect
from django.shortcuts import render, redirect
# HTML Response
def html_view(request):
return render(request, 'template.html')
# Plain Text Response
def text_view(request):
return HttpResponse("Plain text response")
# JSON Response (for APIs)
def json_view(request):
data = {'name': 'John', 'age': 30}
return JsonResponse(data)
# Redirect Response
def redirect_view(request):
return redirect('home')
# 404 Response
from django.http import Http404
def not_found_view(request):
raise Http404("Page not found")
🔹 View Decorators
Decorators add functionality to views, such as requiring login or restricting HTTP methods:
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
# Require user to be logged in
@login_required
def profile(request):
return render(request, 'profile.html')
# Only allow POST requests
@require_http_methods(["POST"])
def submit_form(request):
# Process form
return redirect('success')
# Allow only GET and POST
@require_http_methods(["GET", "POST"])
def contact(request):
if request.method == 'POST':
# Handle form submission
pass
return render(request, 'contact.html')