Class-based views – Django



When building web applications using Django, views play a crucial role in defining the behavior and functionality of the app. While function-based views (FBVs) have been the traditional way of writing views in Django, class-based views (CBVs) have gained popularity due to their simplicity, reusability, and easy implementation of complex functionality.

In this article, we’ll learn the basics of CBVs in Django, their advantages over FBVs, and how to implement them in your Django project.

Advantages of Class-Based Views

CBVs offer several advantages over FBVs:

  1. Code Reusability: CBVs can be easily extended and modified, making them more reusable than FBVs. This is because CBVs are based on object-oriented principles, which makes it easier to inherit and extend from existing classes.
  2. Simplicity: CBVs provide a simplified way to write views in Django. With CBVs, you can write cleaner and more concise code, which is easier to read and maintain.
  3. Complex Functionality: CBVs make it easier to implement complex functionality such as pagination, form handling, and authentication. This is because CBVs provide a range of built-in methods and attributes that can be used to implement such functionality.

Anatomy of a Class-Based View

A CBV is a Python class that inherits from one of Django’s built-in generic views, such as TemplateView, ListView, CreateView, UpdateView, or DeleteView. The following is the basic structure of a CBV:

from django.views.generic import View

class MyView(View):
    # Define methods for handling HTTP requests
    def get(self, request, *args, **kwargs):
        # Handle GET request
        pass

    def post(self, request, *args, **kwargs):
        # Handle POST request
        pass

In the above example, MyView is a CBV that inherits from Django’s View class. The View class is the most basic CBV and provides two methods for handling HTTP requests: get() and post().

Commonly Used Class-Based Views

Django provides several built-in CBVs that can be used to implement common functionality in your web application:

TemplateView

The TemplateView CBV is used to render a template. It’s a simple CBV that doesn’t require any model data to be passed to the template. The following is an example of how to use TemplateView:

from django.views.generic import TemplateView

class HomePageView(TemplateView):
    template_name = 'home.html'

In the above example, HomePageView is a CBV that inherits from Django’s TemplateView class. The template_name attribute specifies the name of the template that will be rendered.

ListView

The ListView CBV is used to display a list of objects from a model. It provides pagination and search functionality out of the box. The following is an example of how to use ListView:

from django.views.generic import ListView
from .models import Book

class BookListView(ListView):
    model = Book
    paginate_by = 10

In the above example, BookListView is a CBV that inherits from Django’s ListView class. The model attribute specifies the model from which the list of objects will be retrieved. The paginate_by attribute specifies the number of objects to display per page.

CreateView

The CreateView CBV is used to create a new object. It provides the implementation of the HTTP GET and POST methods to create a new object. The basic implementation of CreateView requires you to define the model, form_class, and template_name attributes.

Here’s an example of how to use CreateView:

from django.views.generic.edit import CreateView
from myapp.models import MyModel
from myapp.forms import MyModelForm

class MyModelCreateView(CreateView):
    model = MyModel
    form_class = MyModelForm
    template_name = 'myapp/mymodel_create.html'

In the example above, MyModelCreateView inherits from CreateView and defines the model, form_class, and template_name attributes. The model attribute specifies the model to be used for creating the new object, while the form_class attribute specifies the form to be used for creating the new object. The template_name attribute specifies the template to be used for rendering the form.

UpdateView

The UpdateView CBV is used to update an existing object. It provides the implementation of the HTTP GET and POST methods to update an object. The basic implementation of UpdateView requires you to define the model, form_class, and template_name attributes, as well as the pk_url_kwarg attribute, which specifies the name of the URL keyword argument used to retrieve the object to be updated.

Here’s an example of how to use UpdateView:

from django.views.generic.edit import UpdateView
from myapp.models import MyModel
from myapp.forms import MyModelForm

class MyModelUpdateView(UpdateView):
    model = MyModel
    form_class = MyModelForm
    template_name = 'myapp/mymodel_update.html'
    pk_url_kwarg = 'my_model_id'

In the example above, MyModelUpdateView inherits from UpdateView and defines the model, form_class, template_name, and pk_url_kwarg attributes. The model attribute specifies the model to be used for updating the existing object, while the form_class attribute specifies the form to be used for updating the existing object. The template_name attribute specifies the template to be used for rendering the form. The pk_url_kwarg attribute specifies the name of the URL keyword argument used to retrieve the object to be updated.

DeleteView

The DeleteView CBV is used to delete an existing object. It provides the implementation of the HTTP GET and POST methods to delete an object. The basic implementation of DeleteView requires you to define the model, success_url, and template_name attributes, as well as the pk_url_kwarg attribute, which specifies the name of the URL keyword argument used to retrieve the object to be deleted.

Here’s an example of how to use DeleteView:

from django.views.generic.edit import DeleteView
from myapp.models import MyModel

class MyModelDeleteView(DeleteView):
    model = MyModel
    success_url = '/myapp/mymodel_list/'
    template_name = 'myapp/mymodel_confirm_delete.html'
    pk_url_kwarg = 'my_model_id'

In the example above, MyModelDeleteView inherits from DeleteView and defines the model, success_url, template_name, and pk_url_kwarg attributes. The model attribute specifies the model to be used for deleting the existing object, while the success_url attribute specifies the URL to redirect to after the object has been deleted. The template_name attribute specifies the template to be used for rendering the confirmation page. The pk_url_kwarg attribute specifies the name of the primary key parameter that is passed in the URL. By default, it is ‘pk’, but it can be changed using this attribute.

UpdateView

The UpdateView CBV is used to update an existing object in the database. It is similar to the CreateView CBV but is used for updating objects rather than creating new ones.

Here is an example implementation of the UpdateView:

from django.views.generic.edit import UpdateView
from .models import Book

class BookUpdateView(UpdateView):
    model = Book
    fields = ['title', 'author', 'genre']
    template_name = 'book_update.html'
    success_url = '/'
    pk_url_kwarg = 'book_id'

In this example, we are updating a Book object. We specify the model and fields we want to update, the template name to render, and the URL to redirect to upon successful update. The pk_url_kwarg attribute is also used to specify the name of the primary key parameter in the URL.

DeleteView

The DeleteView CBV is used to delete an existing object from the database. It is used to provide a confirmation page before deleting the object.

Here is an example implementation of the DeleteView:

from django.views.generic.edit import DeleteView
from .models import Book

class BookDeleteView(DeleteView):
    model = Book
    template_name = 'book_confirm_delete.html'
    success_url = '/'
    pk_url_kwarg = 'book_id'

In this example, we are deleting a Book object. We specify the model, template name, and URL to redirect to upon successful deletion. The pk_url_kwarg attribute is also used to specify the name of the primary key parameter in the URL.

Complex example of a CBV (uses multiple mixins and methods) –

from django.views.generic import ListView, CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'blog/home.html'
    context_object_name = 'posts'
    ordering = ['-date_posted']
    paginate_by = 5

class PostCreateView(LoginRequiredMixin, CreateView):
    model = Post
    fields = ['title', 'content']
    template_name = 'blog/post_form.html'

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Post
    fields = ['title', 'content']
    template_name = 'blog/post_form.html'

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        return False

class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = Post
    success_url = '/'
    template_name = 'blog/post_confirm_delete.html'

    def test_func(self):
        post = self.get_object()
        if self.request.user == post.author:
            return True
        return False

In this example, we have four CBVs: PostListView, PostCreateView, PostUpdateView, and PostDeleteView.

PostListView is a basic ListView that displays a list of all Post objects in reverse chronological order. It uses pagination to display five posts per page.

PostCreateView is a CreateView that allows authenticated users to create new Post objects. It displays a form with two fields: title and content. When the form is submitted, the form_valid method is called, which sets the author field to the current user and saves the object.

PostUpdateView is an UpdateView that allows authenticated users to update their own Post objects. It uses the UserPassesTestMixin to ensure that only the author of a post can edit it. The test_func method checks if the current user is the author of the post being edited. If not, the user is redirected to a 403 error page.

PostDeleteView is a DeleteView that allows authenticated users to delete their own Post objects. It uses the UserPassesTestMixin to ensure that only the author of a post can delete it. The test_func method works the same as in PostUpdateView.

Overall, CBVs provide a powerful and flexible way to handle common CRUD operations in Django. With mixins and the ability to override individual methods, you can easily customize the behavior of your views to suit your specific needs.

Use of multiple class-based views in Django:

 

# urls.py

from django.urls import path
from .views import (
    BlogListView,
    BlogDetailView,
    BlogCreateView,
    BlogUpdateView,
    BlogDeleteView,
)

app_name = 'blog'

urlpatterns = [
    path('', BlogListView.as_view(), name='blog_list'),
    path('<int:pk>/', BlogDetailView.as_view(), name='blog_detail'),
    path('create/', BlogCreateView.as_view(), name='blog_create'),
    path('<int:pk>/update/', BlogUpdateView.as_view(), name='blog_update'),
    path('<int:pk>/delete/', BlogDeleteView.as_view(), name='blog_delete'),
]

# views.py

from django.views.generic import ListView, DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import BlogPost

class BlogListView(ListView):
    model = BlogPost
    template_name = 'blog/blog_list.html'
    context_object_name = 'posts'
    ordering = ['-created_on']

class BlogDetailView(DetailView):
    model = BlogPost
    template_name = 'blog/blog_detail.html'
    context_object_name = 'post'

class BlogCreateView(CreateView):
    model = BlogPost
    template_name = 'blog/blog_create.html'
    fields = ('title', 'content',)
    success_url = reverse_lazy('blog:blog_list')

class BlogUpdateView(UpdateView):
    model = BlogPost
    template_name = 'blog/blog_update.html'
    fields = ('title', 'content',)
    success_url = reverse_lazy('blog:blog_list')

class BlogDeleteView(DeleteView):
    model = BlogPost
    template_name = 'blog/blog_delete.html'
    success_url = reverse_lazy('blog:blog_list')

 

This code defines five different views for a blog application. The BlogListView and BlogDetailView classes are used for listing and viewing individual blog posts, respectively. The BlogCreateView, BlogUpdateView, and BlogDeleteView classes handle creating, updating, and deleting blog posts. Each view inherits from the appropriate Django class-based view and specifies various attributes such as the template name, model, and success URL.

By using class-based views, this code provides a clean, modular way to handle the various actions a user might take within the blog application. The code is also highly reusable, as it can be easily adapted for use in other applications with minimal modification.

Last Updated on April 29, 2023 by admin

Leave a Reply

Your email address will not be published. Required fields are marked *

Recommended Blogs