I'm adding in a Terms of Service acceptance requirement to our site and am trying to figure out the best way to handle this within Django's authentication framework.
For simplicity's sake, here's a UserProfile
model:
class UserProfile(models.Model):
user = models.OneToOneField(User)
accepted_tos_at = models.DateTimeField(default=None, editable=False, null=True)
So basically what I want to do is to check that accepted_tos_at
is not None
(or in reality greater than the date of the last TOS revision). If it passes this test then we authenticate normally, but if it is None
all views except login
and tos_display
are inaccessible.
What I'm hung up on is how should you go about doing this globally? I would rather not add in user_passes_test
decorators to every one of my views and likewise I'd like to avoid testing for this permission in every one of my views. There must be a cleaner way.
Generally, when you're talking about something that should apply to every view, then, you're talking about middleware. In your case, this is relatively straight-forward:
class AcceptTOSMiddleware(object):
def process_request(request):
login_url = reverse('login')
tos_url = reverse('tos_display')
if request.path not in [login_url, tos_url]:
profile = request.user.get_profile()
if profile.accepted_tos_at is None or \
profile.accepted_tos_at < settings.LAST_TOS_REVISION:
return HttpResponseRedirect(tos_url)
return None
First, this checks if the requested URL is not the login or TOS views. This prevents infinite loops if a redirect is necessary. Then, you check the accepted_tos_at
. I assumed you're simply going to store the last revision date as a setting, so you'll need to modify that if you have other plans. If the TOS needs to be accepted, the user is redirected to the TOS view, otherwise, the middleware returns None
which tells Django to keep processing the request as normal.
Just add the middleware to MIDDLEWARE_CLASSES
and you're golden.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With