I want to redirect access of unauthenticated users to the login page, after which the logged-in user should be redirected to the originally requested page.
According to documentation, this is easily achieved using the @user_passes_test
decorator. But it seems I'd have to decorate every view, which is crazy, there are too many and it's error-prone.
What is a good way to turn on this functionality globally (except for a small fixed set of views, such as login
)? That is, default everything to logged-in-only + handle anonymous viewing explicitly, where needed.
The way I solved this, was to have mixin class, with the decorator (or whatever code you need). Although you have to remember to call the
super(Class, self).get(...)
function, so I guess it's not so different after all.On the other hand, having a set of mixins that does different things I found was quite good at getting a very simple view to do a lot without much code.
Edit
This is how I did in my last project:
The above is then used by the view-classes (I used Django 1.3 with class-based views):
You need a view to handle the login (with URL in
settings.LOGIN_URL
), containing a form with a hidden field callednext
. This field has to be set by a context variable to the page to go to after successful login.If all views inherit from the base mixin (
MyDefaultMixin
in my code above), it will automatically check that the user is logged in iv the view contain an attribute calledlogin_required
and that is set toTrue
.There might be better ways to do this, but this is what I did and it worked very well.
have a look at middleware. these are functions run at various points in the request cycle, e.g. before each view is called.
since you may want to exclude certain views from this, i'd look at e.g. how the csrf middleware works, together with the csrf_exempt decorator.
see
[SOURCE]/django/views/decorators/csrf.py
and[SOURCE]/django/middleware/csrf.py