Class and Function-Based Views

Class and Function-Based Views

ยท

7 min read

Hello, everyone!๐Ÿ‘‹ Welcome to yet another exciting article. Today we will be looking at the pros and cons of class-based views and function-based views in Django and when you should use them.

Introduction

A view function, or view for short, is a python function (callable) that takes in an HttpRequest and returns a HttpResponse. The view basically houses the application logic and handles activities such as querying objects from the database, form rendering, object modifications, and so on.

Django has two types of views namely; function-based views (FBVs) and class-based views (CBVs). In the earlier days of Django, the only available type of view was the function-based views (FBVs) which were very easy to implement and very useful but get too crowded easily, while working on a large project as a result of repeating codes with similar functions (code repetition). Class-based views (CBVs) was introduced to solve the problem of having to write the same code over and over again.

Class-based views provide an alternative way to implement views as python objects instead of functions. Django ships with a variety of CBVs that have pre-defined functionalities that you can reuse and oftentimes extend to suit your application needs.

Note: Class-based views does not replace function-based views

Function-Based Views (FBVs)

Function-based views are views in Django that are defined with functions. These python functions take in an HttpRequest and return an HttpResponse. In this approach, all the intended logic for the view must be included in the view, and it is disadvantaged by code repetition (reinventing the wheel) and becomes lengthy easily.

Pros

  • Simple and easy to implement
  • Clean and readable code
  • straight-up implementation of decorators
  • Explicit code flow

    Cons

  • HTTP methods are handled via conditional branching
  • Very difficult to extend and reuse code
# example of a function-based view
def index(request):
    posts = Post.objects.all()
    context = {
              'posts' = posts
    }
    return render(request, 'app/index.html', context)

Class-based views (CBVs)

At their core, CBVs are python objects and they are an alternative method of implementing views in Django. class-based views do not replace function-based views but have a certain difference and advantage when compared to function-based views.

Pros

  • Code reusability (Inheritance) - a view class can be inherited by another view class and modified for a different use case
  • Code extendability - CBVs can be extended to include more functionalities using Mixins
  • Built-in generic class - To perform generic functions such as basic CRUD operations
  • DRY code approach - reduce code repetition
  • Code Structuring - you respond to different HTTP requests with different class instance methods (no conditional branching).

    Cons

  • Implicit code structure
  • Harder to read and comprehend
  • Implementing decorators is not straight-forward you need extra imports or method override
# Example of class-based views 
class index(View):
      model = Post
      template_name = 'app/index.html'

This class-based view does the same thing as the function-based view example above but makes code relatively shorter and harder to read due to implicit code flow.

Django Generic Class-Based Views

The generic class-based views were developed to handle the common use cases in Web applications, such as creating new objects, form rendering, pagination, list views, etc. And can be implemented from the core django module django.views.generic.

Django ships with a set of views, Mixins, and generic class-based views. The goal is to speed up development and handles performing common web application tasks without having to reinvent the wheel over and over again.

let's look at an example of class-based view and generic class-based view

# CLASS BASED VIEW 
from django.shortcuts import render, redirect 
from django.urls import reverse
from django.views import View


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

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

  def post(self, request, *args, **kwargs):
    form = self.form_class(request.POST)
    context = {'form':form}
    if form.is_valid():
      form.save()
      return redirect(reverse('list-view'))
    else:
      return render(request, self.template_name, context)

Now let's see the same example using generic class-based view

# GENERIC CLASS BASED VIEW
from django.views.generic import CreateView

class MyCreateView(CreateView):
   model = MyModel 
   form_class = MyForm

With generic class-based views that all the code we need to perform the same task as the class-based view example above.

Conclusion

The question of which type of view to use depends on the context and the application needs. As stated earlier in the article, class-based views do not replace function-based views.

In some instances, a function-based view is preferred and in other cases, a class-based view is advised. For example;

If you want to implement a detailed view and you can get that working by subclassing the DetailView class and overriding the attributes. awesome! Go for class-based views.

But

When implementing a complex operation that handles multiple forms at once, a function-based view will do a better job. The general advice is to use whatever serves your application needs best.

Thanks for reading๐Ÿ‘‹ see you in the next one!