You have no excuses now, use this free credit to launch your projects now on Digital Ocean, you're free to spend it whenever you want within the following 60 days.
Table of contents
How do permissions and its groups work in Django?
How do permissions and its groups work in Django?
When I first learned that Django had a permissions system, many years ago, it seemed rather esoteric, not very useful and easy to replicate, how wrong I was back then. Then I realized that the built-in permissions system was a marvel and saved a lot of code, and was quite robust and tested by some of the largest companies in the world.
If you have not yet decided to use Django and are investigating its features check out my post on the advantages and disadvantages of the Django web development framework .
On the other hand, if you already have some practice with Django, you may want to deepen what you know with this free book, called la guía definitiva de Django .
How to create permissions in Django?
Every time you create a model and run migrations 4 permissions (add, edit, delete and view) are automatically created in django.contrib.auth for that object.
On the other hand, the user model has a ManyToMany relationship with the Permissions model (which stores the above permissions) and the Groups model. So we already have a relationship between users, groups and permissions that we can take advantage of.
The permissions that Django creates come in the form of ._ or app.action_model.
app.add_modelo # Para añadir modelos
app.edit_modelo # Para editar modelos
app.delete_modelo # Para borrar modelos
app.view_modelo # Para ver modelos
# por ejemplo:
# streaming.add_pelicula
# tienda.edit_articulo
# encuestas.delete_encuesta
# vapor.view_videojuego
Need to learn everything Django has to offer?
AdTo master Django you must understand how it works, how a HTTP request goes to the router, which pass the request data to the appropiate function (or class) and then how you can Django's ORM to interact with the database and return a response if you want a detailed explanation of each step, educative has a course on that, certificate included, and Python is covered (in case you don't know Python) link below.
Add or remove permissions to a user
To add or remove permissions to a user we will make use of the methods provided by Django
To add permissions one by one we pass them to the add() method.
user.permissions.add(permiso1, permiso2, ...)
To remove permissions we pass the permission we want to remove to the remove() method.
user.permissions.remove(permiso1, permiso2, ...)
If we want to set a list of permissions we simply match the permissions attribute to the list we want it to have.
user.permissions = [lista_de_permisos]
To remove all permissions for a user we use the clear() method.
user.permissions.clear()
Checking permissions for a user
Once we have assigned permissions, we can limit the behavior of a user to the permissions he/she has. For example, Patreon only shows its content to users who periodically donate to a content creator and even within a single account there are different permissions depending on the amount of money you donate.
Check what permissions a user has
The get_all_permissions() method returns a list of all the permissions a user has.
user.get_all_permissions()
Check the permissions of the groups a user belongs to
This will return the permissions that a user obtains by the groups to which he/she belongs.
user.user.get_group_permissions()
Check if a user has a permission
We can check if a user has a unique permission with the has_perm() method. It will return True if the user has the permission. If the user has the permissions but its user instance has the active property equal to False, it will return False.
user.has_perm("app.accion_modelo")
Check if a user has a set of permissions
has_perms is quite useful if we want to check if a user has a set of permissions. It will return True, only if it has all the permissions. Like the previous one, **will return False if the user is not active, even if he has the permissions **.
user.has_perms(["app.edit_modelo", "app.delete_modelo"]) # por ejemplo videogame_store.edit_videogame, videogame_store.delete_videogame
Check if a user has any permissions
Maybe we just want to check the existence of any permissions, that’s what has_module_perms() is for. It returns True if the user has any permissions for the application tag we pass it. In the same way, it returns False for inactive users.
user.has_module_perms('etiqueta_de_la_app') # por ejemplo videogame.view_videogame
# models.py
class tuModelo(models.Model):
class Meta:
app_label = 'etiqueta_de_la_app'
Applying permissions to limit actions
We can apply permissions to protect our views by wrapping them in a decorator.
Checking with user_passes_test
This function requires an object as argument and this object must accept the user object as its argument. Leaving that aside, this test can contain anything you want, from checking a user field, permissions, corroborating a deadline, etc.
There is a second optional parameter, the url to redirect to for unauthenticated users, which takes the value of settings.LOGIN_URL (yes, the one you specify in your configuration file) if none is specified.
def can_delete_and_edit(user):
return user.has_perm("app.edit_modelo") and user.has_perm("app.delete_modelo")
@user_passes_test(can_delete_and_edit, login_url="/login/")
def manage_videogame(request):
pass
Checking with permissions_required
Similarly, it has a second optional parameter, the url to redirect to for unauthenticated users, which takes the value of settings.LOGIN_URL if none is specified.
from django.contrib.auth.decorators import permission_required
@permission_required('app.edit_videogame', login_url="/login/")
def edit_videogame(request):
# ...
Applying permissions in templates
Django templates are no longer as popular as they used to be, due to the rise of microservices and frontend frameworks such as React, Vue, Angular, etc. Still, if you want to use them in templates you can access permissions as follows:
Update: Htmx can bring permissions back to life in the Django template system.
{% if perms.app.action_model %}
Para comprobar si el usuario tiene un permiso en específico
{% endif %}
{% if perms.app %}
Para comprobar si el usuario tiene algún permiso para esa app
{% endif %}
Permission groups in Django
As you know, using groups is a very convenient way to assign a set of permissions. Maybe you have a paid application and you want all users with the basic plan to have a set of permissions, while premium users have extra permissions. To organize the permissions and assign them in a simpler way we can use groups. You can access these groups and assign permissions from the administration panel or from the Python terminal.
Create permission groups
We can also create them directly from the Python terminal
from django.contrib.auth.models import Group
Group.objects.create(name="Premium")
premium = Group.objects.get(name="Premium")
Assign permissions to a group
If we already have a group and we want to assign permissions to it we use practically the same set of methods that we use for a user.
To set up a permission list
premium.permissions.set([lista_de_permisos])
To add permissions, either a list or one by one.
premium.permissions.add(permiso1, permiso2, ...)
To remove permissions, either a list or one by one
premium.permissions.remove(permiso1, permiso2, ...)
To remove all permissions from a group
premium.permissions.clear()
Adding or removing users from a group
To add a permission group we use the same methods as in the previous examples: add, remove, clear, etc.
# agregar a un usuario a varios grupos
user.groups = group_list
# Agregar un usuario a uno o varios grupos
user.groups.add(grupo1, grupo2,...)
# Removemos un usuario de uno o varios grupos
user.groups.remove(grupo1, grupo2,...)
# Eliminamos a un usuario de todos los grupos
user.groups.clear()
Create custom permissions in Django
We can add custom permissions to a model, we will use the sub class Meta of our model and assign the property permissions to a tuple of tuples, where each tuple has the name of the permission and its description.
permissions = (('permiso1', 'descripción 1'), ('permiso 2', 'descripción 2'))
We can name these permissions as we wish, then give that permission to certain users and then check if a user has any of our permissions using the methods seen previously.
class usuarioPersonalizado(AbstractUser):
# ...
class Meta:
permissions = (
('puede_ver_contenido_premium', 'Puede ver contenido para usuarios premium'),
('puede_ver_contenido_básico', 'Puede ver contenido para usuarios básico'))
If we now run the migrations, we will notice that we can now add the permissions we created from the administration panel and from the Python terminal.
python manage.py makemigrations
python manage.py migrate
Remember to check Django’s documentation on permissions for a more in-depth post.