Django: Невозможно применить функциональный декоратор представления к представлению на основе классов

Я перехожу от обычных представлений, основанных на функциях, к представлениям, основанным на классах. Одной из вещей, которую я не смог перенести, были декораторы, которые я использовал. Декоратор, о котором идет речь, проверяет, действительны ли учетные данные текущего пользователя, а затем выполняет декорированную функцию:

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

Раньше я мог просто украсить свою функцию, сделав

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

Однако, когда я пытаюсь применить его к моему представлению на основе класса тем же способом, я получаю ошибку, говорящую __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 

Я знаю, что это не тот способ, которым вы должны применять декоратор, поэтому я пробовал использовать различные подходы. Либо добавить декоратор к urls.py, либо добавить @method_decorator(custom_auth, name="dispatch"), либо просто переопределить метод диспетчеризации, но ни один из них не работает. Все они дают мне одну и ту же ошибку.

В чем может быть проблема? Может быть, мне следует использовать пользовательский миксин?

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

из документации django 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'

и нет необходимости добавлять пользователя к вызову функции в декораторе. Он уже есть в запросе

Используйте @method_decorator следующим образом:

from django.utils.decorators import method_decorator

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

Редактирование:

Попробуйте сделать свой собственный mixin как класс и наследовать его для использования в CBV классе так:

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 

Вернуться на верх