Overview

In this guide I will show you how to create custom mixins in django class based views.

1. Create a class RedirectMixin

This class is responsible for creating other utility mixins and redirecting them to a particular url if condition is not satisfied.

This class will be used by other custom mixin classes and those classes have to implement test_func  to set a condition for redirecting.

from django.shortcuts import redirect

class RedirectMixin:
    """
    Redirect to redirect_url if the test_func() method returns False.
    """

    redirect_url = None

    def get_redirect_url(self):
        """
        Override this method to override the redirect_url attribute.
        """
        redirect_url = self.redirect_url
        if not redirect_url:
            raise ImproperlyConfigured(
                '{0} is missing the redirect_url attribute. Define {0}.redirect_url or override '
                '{0}.get_redirect_url().'.format(self.__class__.__name__)
            )
        return str(redirect_url)

    def test_func(self):
        raise NotImplementedError(
            '{0} is missing the implementation of the test_func() method.'.format(self.__class__.__name__)
        )

    def get_test_func(self):
        """
        Override this method to use a different test_func method.
        """
        return self.test_func

    def dispatch(self, request, *args, **kwargs):
        test_result = self.get_test_func()()
        if not test_result:
            return redirect(self.get_redirect_url())
        return super().dispatch(request, *args, **kwargs)

2. Now create a custom mixin by inheriting this class

We will create a custom mixin to redirect user to some other view if a condition is not met. This mixin will redirect users to a different view if user is authenticated or logged_in.

class LoggedInRedirectMixin(RedirectMixin):
    def test_func(self):
        return self.request.user.is_authenticated

3. Now use the above mixin in a view

from django.views.generic import TemplateView
from .mixins import LoggedInRedirectMixin
from django.urls import reverse_lazy

class LoginView(LoggedInRedirectMixin,TemplateView):
    template_name="account/login.html"

    #("pages:dashboard") - Its a url namespace, you can learn more about them here: https://docs.djangoproject.com/en/3.0/topics/http/urls/#url-namespaces
    redirect_url=reverse_lazy("pages:dashboard")
    
    # redirect_url = "/some-url/" #this is also valid