-->

Django - Correct way to pass arguments to CBV deco

2019-05-14 15:14发布

问题:

The docs feature nice options for applying decorators such as login_required to Class Based Views.

However, I'm a little unclear about how to pass specific arguments along with the decorator, in this case I'd like to change the login_url of the decorator.

Something like the following, only valid:

@login_required(login_url="Accounts:account_login")
@user_passes_test(profile_check)
class AccountSelectView(TemplateView):
    template_name='select_account_type.html'

回答1:

You should use @method_decorator with class methods:

A method on a class isn’t quite the same as a standalone function, so you can’t just apply a function decorator to the method – you need to transform it into a method decorator first. The method_decorator decorator transforms a function decorator into a method decorator so that it can be used on an instance method.

Then just call decorator with arguments you need and pass it to method decorator (by calling decorator function that can accept arguments you will get actual decorator on exit). Don't forget to pass the name of the method to be decorated as the keyword argument name (dispatch for example) if you will decorate the class instead of class method itself:

@method_decorator(login_required(login_url="Accounts:account_login"),
                  name='dispatch')
@method_decorator(user_passes_test(profile_check), name='dispatch')
class AccountSelectView(TemplateView):
    template_name='select_account_type.html'