When using the django.contrib.auth application in your project you have a number of options available for permission checking. In this recipe we will go over a number of possibilities provided by Django and offer a custom pattern you can implement.

Simple testing of User objects

When using function based views in your Django apps you can use the user_passes_test  decorator. This is a function decorator provided by Django that you can apply to a view function. Like the decorator name says, it tests a user object. The callable you pass the decorator should take a User object and return True  when your test passes. Return False  from your callable to perform a redirect.

Here’s an example using the user_passes_test  decorator. In our example we test if the user has more than 3 post objects before they can access the view.

Read the Django documentation for user_passes_test

When you use Class Based Views there is a Mixin called UserPassesTestMixin  you can add to your CBV’s. Simply add the Mixin to you class based view and implement a test_func  method to validate any business logic. Return True  when validation passes or return False  when it doesn’t.

Let’s recreate our example above using CBV’s and the UserPassesTestMixin .

Read the Django documentation for UserPassesTestMixin

 

Simple permission checking

If you need to check a single permission you can use the permission_required  decorator. Using this decorator requires no callable, you just supply it with the name of the permission you want to check.

Let’s have a look at an example where we limit access to a view unless the user has the ‘books.can_translate’ permission.

If you need to check for multiple permissions you can pass an iterable (list, tuple, …) of permission names instead of a single permission.

Read the Django documentation for permission_required

A similar solution is available for you Class Based Views through the PermissionRequiredMixin .

If you need to check multiple permissions you can pass an iterable like so  permissions_required = ('books.can_translate', 'books.can_change') .

A custom pattern

When implementing complex business logic in your views there is an alternative you can implement. Using function based views it involves creating a function that validates your custom logic. If the permission check fails you raise a PermissionDenied  exception.

The advantage of this approach is that you can apply your custom validation function in any way you like, using any parameters you require. Even if you don’t use your validation function in multiple views it pays off to move the validation code to another function. Reading your view code is a lot cleaner when you see a single line that says  user_can_translate_book(user, book)  than a twelve line block of code.

Conclusion

When you use the django.contrib.auth application in your projects there are a number of options available for permission checking. Be sure to check up on the Django documentation for Using the Django authentication system.

Leave a Reply

Your email address will not be published. Required fields are marked *