Open In App

Class Based vs Function Based Views - Which One is Better to Use in Django?

Last Updated : 19 May, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Django, a powerful Python web framework, has become one of the most popular choices for web development due to its simplicity, scalability and versatility. One of the key features of Django is its ability to handle views and these views can be implemented using either Class-Based Views (CBVs) or Function-Based Views (FBVs).

While both types of views allow developers to define how data is presented to the user, they differ significantly in how the logic is structured.

Function-Based Views

FBVs were the original approach in Django. These views are simply Python functions that receive an a HTTP request, process it and return an HTTP response.

Pros of FBVs:

  1. Simple and Easy to Understand: FBVs are easier to grasp, especially for beginners. The flow of control in a function is straightforward, making it easier to debug and maintain for small projects.
  2. Explicit Code Flow: In FBVs, the code is more explicit. You define each HTTP method (GET, POST, etc.) manually within the function, which makes it clear exactly what happens for each HTTP verb.
  3. Flexible: FBVs give you full control over the view logic and allow for quick implementation, especially for small projects or when you have a simple use case.
  4. Straightforward Decorator Usage: FBVs work very well with decorators, such as @login_required, @require_http_methods or custom decorators that can be applied directly to the function.

Cons of FBVs:

  1. Code Duplication: As your application grows, you may end up with repeated code in multiple views. For instance, handling form validation or querysets might require writing similar code in many views.
  2. Conditional Branching: FBVs often require multiple if conditions to handle different HTTP methods (GET, POST). As the logic grows more complex, it can lead to messy and hard-to-maintain code.

Here is an example of a function-based view:

Python
def example_create_view(request, pk):
  template_name = 'form.html'
  form_class = FormExample

  form = form_class

  if request.method == 'POST':
    form = form_class(request.POST)
    if form.is_valid():
      form.save()
      return HttpResponseRedirect(reverse('list-view'))

  return render(request, template_name, {'form': form})

All the above cons of FBVs you won't find in class-based views. You won't have to write the same code over and over in your boilerplate. 

Class-Based Views

Class-Based Views were introduced to Django to address some of the shortcomings of FBVs, particularly code duplication. They allow for more organized and reusable view logic by using object-oriented principles like inheritance and mixins.

Pros of CBVs:

  1. Code Reusability: CBVs promote the DRY (Don’t Repeat Yourself) principle. Common functionalities like form handling, object creation and deletion are abstracted into reusable views like CreateView, UpdateView and DeleteView, which you can easily extend.
  2. Better Code Organization: In CBVs, you can structure the code by breaking it down into different methods (get, post, etc.), which helps keep the logic clean and organized.
  3. Inheritance and Mixins: CBVs allow you to inherit from other views and modify their behavior. You can also use mixins to add functionality in a modular way.
  4. Built-in Generic Views: Django provides several built-in generic views for common patterns like creating, updating, listing and deleting objects, which speeds up development.

Cons of CBVs:

  1. More Complex to Understand: CBVs introduce a level of abstraction that may be difficult for beginners to understand. You need to learn how to extend and customize views, which can require more time to get familiar with.
  2. Implicit Code Flow: The flow of code in a CBV is less explicit than in FBVs. The dispatch() method and as_view() method introduce extra layers of complexity that might make debugging more difficult.
  3. Extra Imports and Method Overrides: CBVs may require additional imports and method overrides, which can make them feel less intuitive in certain cases.

Below is an example of a class-based view:

Python
class MyCreateView(View):
  template_name = 'form.html'
  form_class = MyForm

  def get(self, request, *args, **kwargs):
    form = self.form_class
    return render(request, template_name, {'form': form})

  def post(self, request, *args, **kwargs):
    form = self.form_class(request.POST)
    if form.is_valid():
      form.save()
      return HttpResonseRedirect(reverse('list-view'))
    else:
      return render(request, self.template_name, {'form': form})
  • In Django, even though the as_view() method is not explicitly defined in this example, it is inherited from the base View class. The as_view() method acts as a class method that creates an instance of the view and returns a callable that can handle a request.
  • When a request is received, as_view() internally calls the dispatch() method on the view instance, which then determines the appropriate handler method (get(), post(), etc.) to call based on the HTTP method of the request.
  • Using as_view() also allows you to override class attributes dynamically when defining URL patterns, for example:
Python
urlpatterns = [
    url(r'^new/$', MyCreateView.as_view(), name='original-create-view')
    url(r'^new_two/$', MyCreateView.as_view(template_name='other_form.html',
                    form_class='MyOtherForm'), name='modified-create-view')
  ]

Once you start using the Django generic class-based views, you will be able to over-write the helper method like get_form_class and get_template_names. You can insert the additional logic at these points instead of just overriding the class attribute. One of the good examples of it is...ModelFormMixin. form_valid method is overridden. With the updated value stored in self.object() form_valid method is overridden. 

Django Generic Class-Based View

Django’s generic class-based views take CBVs to the next level. They provide pre-built views for common tasks such as creating, updating, listing and deleting objects. These views significantly reduce boilerplate code by automatically handling common functionalities. For instance, the CreateView automatically handles displaying a form, validating it and saving the object. Example:

Python
from django.views.generic import CreateView
from .models import MyModel
from .forms import MyModelForm

class MyCreateView(CreateView):
    model = MyModel
    form_class = MyModelForm
    template_name = 'form.html'
    success_url = '/success/'


In this example:

  • CreateView automatically provides form handling logic.
  • You just need to specify the model, form, template and success URL.
  • The view is already wired to handle the GET and POST methods, significantly reducing boilerplate code.

FBVs vs CBVs: When to Use Each

When to Use Function-Based Views:

  • Small, Simple Views: FBVs are ideal for smaller, straightforward views where you don’t need to repeat the logic.
  • Quick Prototyping: If you need to quickly implement a feature with minimal overhead, FBVs are faster to write.
  • More Control: If you want full control over your view logic and don’t need the abstraction that CBVs provide, FBVs are better suited.

When to Use Class-Based Views:

  • Reusable Logic: CBVs are great when you need to reuse common view logic like form handling or object CRUD operations.
  • Complex Views: When you have complex views with multiple methods (e.g., handling GET, POST, PUT requests) or need inheritance and mixins for modular code, CBVs offer a cleaner approach.
  • Built-in Functionality: For common operations like creating, updating or deleting database objects, Django's generic CBVs can save you a lot of time and effort.

Next Article
Practice Tags :

Similar Reads