Django: Unable to Apply Function View Decorator to Class Based View

I'm migrating from regular function based views, to class based views. One of the things that I couldn't migrate were the decorators I used. The decorator in question checks if the credentials of the current user are valid and then executes the decorated function:

def custom_auth(function):

    @wraps(function)
    def wrap(request, *args, **kwargs):
        
        # Logic for validating if user has correct credentials

        # Fetches the user that accessed the function
        user_object = User.objects.get(username=request_username)       
        
        # Try to execute the decorated function. If it fails, redirect
        # to previous page and show an error popup   
        try:
            return function(request, user=user_object, *args, **kwargs)
        except:
            # Logic for displaying the popup

Previously I could just decorate my function by doing

@custom_auth
def view(request, *args, **kwargs):
    # View logic

However, when I try to apply it to my class based view in the same way, I get an error saying __init__() takes 1 positional argument but 2 were given: user='username', view='cbvview'

@custom_auth
class CBV(View):

    def get(self, request, *args, **kwargs):
        # Get request logic 

I know that this is not the way you are supposed to apply the decorator, so I tried with different approaches. Either adding the decorator to urls.py, adding the @method_decorator(custom_auth, name="dispatch") or simply overriding the dispatch method, but none of them work. All of them give me the same error.

What could be the issue? Maybe I should use a custom mixin instead?

from django.utils.decorators import method_decorator
class CBV(View):
    
  @method_decorator(custom_auth)
  def get(self, request, *args, **kwargs):
      # Get request logic

from django docs https://docs.djangoproject.com/en/4.1/topics/class-based-views/intro/

@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
    template_name = 'secret.html'

and there is no need to add the user to the function call in the decorator. It is already in the request

Use @method_decorator like following:

from django.utils.decorators import method_decorator

@method_decorator(custom_auth,name="dispatch")
class CBV(View):
    
  def get(self, request, *args, **kwargs):
      ...

Edit:

Try to make your own mixin as class and inherit it to be used in CBV class so:

class CustomAuthMixin:
    def dispatch(self, request, *args, **kwargs):
        # Logic for validating if user has correct credentials

        # Fetches the user that accessed the function
        user_instance = User.objects.get(username=request_username)       
        
        # Try to execute the decorated function. If it fails, redirect
        # to previous page and show an error popup   
        try:
            return super().dispatch(request, user=user_instance, *args, **kwargs)
        except:
            # Logic for displaying the popup

class CBV(CustomAuthMixin, View):

    def get(self, request, *args, **kwargs):
        # Get request logic 

Back to Top