Class Based Views - potatoscript/django GitHub Wiki
Imagine youβre building with LEGO bricks. Function-Based Views (FBVs) are like building from scratch every time π§±
Class-Based Views (CBVs) are like prebuilt LEGO sets β faster, cleaner, and easier to reuse! π§°β¨
π§ Function-Based View (FBV)
def hello_view(request):
return HttpResponse("Hello!")
π Class-Based View (CBV)
from django.views import View
from django.http import HttpResponse
class HelloView(View):
def get(self, request):
return HttpResponse("Hello!")
β‘οΈ In your urls.py
:
from django.urls import path
from .views import HelloView
urlpatterns = [
path('hello/', HelloView.as_view(), name='hello'),
]
π as_view()
turns your class into a usable view!
Benefit | Explanation |
---|---|
β Reusable | You can inherit and extend views |
β Organized | Separate logic by HTTP methods (GET, POST...) |
β Shorter Code | Prebuilt views do the heavy lifting |
β Easier to maintain | Especially for big projects ποΈ |
class MyView(View):
def get(self, request):
# handle GET requests
def post(self, request):
# handle POST requests
from django.views import View
from django.shortcuts import render
class HomePageView(View):
def get(self, request):
return render(request, 'home.html')
path('', HomePageView.as_view(), name='home'),
π templates/home.html
<h1>π‘ Welcome to the Home Page!</h1>
<p>This is rendered using a Class-Based View.</p>
CBV | What It Does |
---|---|
TemplateView |
Just show a template |
ListView |
Show a list of things from the DB |
DetailView |
Show details about one thing |
CreateView |
Form to create a new thing |
UpdateView |
Form to update a thing |
DeleteView |
Confirm then delete a thing |
from django.views.generic import TemplateView
class AboutView(TemplateView):
template_name = 'about.html'
# urls.py
path('about/', AboutView.as_view(), name='about'),
π‘ No need to define get()
β itβs already built in!
Letβs say you have this model:
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
Now show all posts:
from django.views.generic import ListView
from .models import Post
class PostListView(ListView):
model = Post
template_name = 'posts.html'
context_object_name = 'posts'
posts.html
<h1>π Blog Posts</h1>
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
{% endfor %}
</ul>
from django.views.generic import DetailView
from .models import Post
class PostDetailView(DetailView):
model = Post
template_name = 'post_detail.html'
URL:
path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
Template:
<h2>{{ object.title }}</h2>
<p>{{ object.content }}</p>
π pk
is the postβs primary key (ID)
from django.views.generic.edit import CreateView
from .models import Post
from django.urls import reverse_lazy
class PostCreateView(CreateView):
model = Post
fields = ['title', 'content']
template_name = 'post_form.html'
success_url = reverse_lazy('home')
πΎ reverse_lazy()
= safely redirect after saving
Template:
<h2>π New Post</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Create</button>
</form>
Same pattern:
from django.views.generic.edit import UpdateView, DeleteView
class PostUpdateView(UpdateView):
model = Post
fields = ['title', 'content']
template_name = 'post_form.html'
success_url = reverse_lazy('home')
class PostDeleteView(DeleteView):
model = Post
template_name = 'post_confirm_delete.html'
success_url = reverse_lazy('home')
View | Purpose | Base Class |
---|---|---|
Show page | TemplateView |
|
List stuff | ListView |
|
Detail | DetailView |
|
Create | CreateView |
|
Update | UpdateView |
|
Delete | DeleteView |
URL | View |
---|---|
/ |
HomePageView |
/about/ |
AboutView |
/posts/ |
PostListView |
/post/1/ |
PostDetailView |
/create/ |
PostCreateView |
/post/1/edit/ |
PostUpdateView |
/post/1/delete/ |
PostDeleteView |