Django Views, Forms & Auth
In Django, incoming HTTP requests hit urls.py, which matches the URL path and routes execution to the appropriate View function or class in views.py.
Function-Based Views (FBVs) vs Class-Based Views (CBVs):
- Function-Based Views (FBVs): Simple, explicit, and easy to read. You handle HTTP methods manually using
if request.method == "POST":. - Class-Based Views (CBVs): Object-oriented views that promote code reuse via inheritance and mixins (e.g.
ListView,DetailView,CreateView).
# 1. URL Dispatcher: store_app/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.product_list_view, name="product_list"),
path("/", views.product_detail_view, name="product_detail"),
path("create/", views.ProductCreateView.as_view(), name="product_create"),
]
# 2. View Handlers: store_app/views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.views.generic import CreateView
from .models import Product
# Function-Based View (FBV):
def product_list_view(request):
"""Fetches and displays all active products."""
products = Product.objects.filter(is_active=True).order_by("-created_at")
context = {"products": products, "page_title": "Product Catalog"}
return render(request, "store/product_list.html", context)
# FBV with 404 Guard:
def product_detail_view(request, product_id):
"""Fetches single product or returns 404 automatically."""
product = get_object_or_404(Product, id=product_id, is_active=True)
return render(request, "store/product_detail.html", {"product": product})
# Class-Based View (CBV):
class ProductCreateView(CreateView):
model = Product
fields = ["title", "category", "price", "stock"]
template_name = "store/product_form.html"
success_url = "/products/"
get_object_or_404(Model, id=...) queries the database and automatically raises an Http404 exception if no record exists, eliminating manual try-except Model.DoesNotExist blocks.
Django includes an enterprise-grade authentication system in django.contrib.auth, providing secure User models, password hashing, session management, and access decorators.
The Power of ModelForms:
A ModelForm automatically inspects your Django Model and generates corresponding HTML form widgets with automatic server-side validation, error messages, and direct form.save() database persistence!
# 1. Defining a ModelForm: store_app/forms.py
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ["title", "category", "price", "stock"]
widgets = {
"title": forms.TextInput(attrs={"class": "form-control", "placeholder": "Enter product title"}),
"price": forms.NumberInput(attrs={"class": "form-control", "min": "0"}),
}
# 2. Authenticated View Protected with @login_required: store_app/views.py
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
@login_required(login_url="/accounts/login/")
def create_product_view(request):
"""Only logged-in users can access this page."""
if request.method == "POST":
form = ProductForm(request.POST)
if form.is_valid(): # Validates data types, lengths, and constraints!
product = form.save() # Automatically inserts row into DB!
return redirect("product_detail", product_id=product.id)
else:
form = ProductForm()
return render(request, "store/product_form.html", {"form": form})
When rendering forms in templates, always include {% csrf_token %} inside the <form>. form.is_valid() validates clean data, checks constraints, and populates form.errors if validation fails.
Every POST form in a Django template must include the {% csrf_token %} template tag. If omitted, Django's CSRF middleware will immediately reject the submission with an HTTP 403 Forbidden error.
Simulate Django's authentication check: write a function check_login_status(user) that returns "Access Granted" if user.is_authenticated is True, else "Redirecting to /login/".
class MockUser:
def __init__(self, name, is_auth):
self.username = name
self.is_authenticated = is_auth
def protect_dashboard(user):
if not user.is_authenticated:
return "๐ HTTP 302: Redirecting to /accounts/login/?next=/dashboard/"
return f"โ
Access Granted: Welcome to Dashboard, {user.username}!"
print(protect_dashboard(MockUser("Anonymous", False)))
print(protect_dashboard(MockUser("Balaji", True)))
Q What is the difference between authenticate() and login() in Django?
authenticate(request, username=..., password=...) verifies credentials and returns a User object (or None). login(request, user) attaches the authenticated user to the current session cookie.
Q What are Django Context Processors?
Context processors are functions that automatically inject variables into the context of every rendered template across the entire site (e.g. {{ user }}, {{ request }}, {{ messages }}).
Q How do I extend the default User model in Django?
The recommended practice is to create a CustomUser model inheriting from AbstractUser, configured via AUTH_USER_MODEL = "users.CustomUser" in settings.py.