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?
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):
...
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