41π
Now, the decorators in Python work from the inside out
Well I guess that depends on your definition of inside out. In your case, you want @login_required
to execute first, and so it should be the "outermost" (top) decorator.
As you noted, your last example works, and is indeed the correct way to do this.
edit
The confusion might be how these particular decorators work.
@login_required(@original_view)
returns a new view, which first checks if you are logged in, and then calls original_view
so
@login_required(
@active_required(
@my_view
)
)
first checks if you are logged in, then
first(second) checks if you are active, then
runs my_view
18π
Decorators are applied in the order they appear in the source. Thus, your second example:
@login_required
@active_required
def foo(request):
...
is equivalent to the following:
def foo(request):
...
foo = login_required(active_required(foo))
Thus, if the code of one decorator depends on something set by (or ensured by) another, you have to put the dependent decorator βinsideβ the depdended-on decorator.
However, as Chris Pratt notes, you should avoid having decorator dependencies; when necessary, create a single new decorator that calls both in the right order.
- [Django]-Django TypeError: render() got an unexpected keyword argument 'renderer'
- [Django]-How to get GET request values in Django Views?
- [Django]-What is {% block content %} and {% endblock content %} for in Django?
12π
It only really makes sense to stack decorators if they have truly unique functionality. Based on your description, thereβs never going to be a scenario where you will want to use active_required
but not login_required
. Therefore, it makes more sense to have a login_and_active_required
decorator that checks both and branches accordingly. Less to type, less to document, and negates the problem.
- [Django]-Best way to write an image to a Django HttpResponse()
- [Django]-Django: Can I create a QueryDict from a dictionary?
- [Django]-What's the difference between `from django.conf import settings` and `import settings` in a Django project
5π
To explain it a bit more (I was also confused at first): active_required
is applied first in a sense that it takes my_view
and wraps it in some code. Then login_required
is applied and wraps the result in some more code.
But when this wrapped version of my_view
is actually invoked, first the code added by login_required
is executed (checking that youβre logged in), then the code added by active_required
is executed (checking that youβre active) and then finally my_view
is executed.
- [Django]-Django admin: How to display the field marked as "editable=False" in the model?
- [Django]-Http POST drops port in URL
- [Django]-How do I test if a certain log message is logged in a Django test case?