Easiest way to authorize users using Django Permissions, Roles, and Groups for Beginners

In this post, we’ll be learning about the Easiest way to authorize users using Django Permissions, Roles, and Groups for Beginners, and also I will cover all the important aspects you must know as a intermediate and beginner.

Table of Contents

Introduction

When it comes to authentication and permissions checking Django provides built-in Permissions through which we can create and validate if the user has permission to access certain data in the application.
Django provides default models for storing permissions. The developer has the freedom to create additional custom permissions and extend the functionality of their application.
By default django provides with four permission they are add_<model_name>, change_<model_name>, delete_<model_name>, view_<model_name>.

Create Model and add permissions

Let’s get started by creating a Team model to test our permissions. I have created a new app called `permissions` and registered it to INSTALLED_APPS in settings.py file.
Click here to learn more about installing Django, creating a project, and app.

To create a model goto models.py in app permissions.

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Team(models.Model):
    team_id = models.AutoField(primary_key=True)
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='user')
    name = models.CharField(max_length=150)

    class Meta():
        app_label = "permissions"
        db_table = 'teams'
        verbose_name = 'Team'
        verbose_name_plural = 'Teams'
        permissions = [
            ('can_edit_team', 'Can edit team'),
        ]

Then make migrations for model Team using python manage.py makemigrations permissions command. After migrations, the user python manage.py migrate creates a table for a model in the database.

You can see that our table teams has been created and when you got to table auth_permission you can see that Django has automatically added those four default permissions which I have mentioned in the introduction and with custom permission we have specified in Team model that is can_edit_team permission.

Add permissions to the user

Django permissions are stored in a table auth_permission and user permissions are stored in many to many relationship tables auth_user_user_permissions which has user_id and permission_id columns.

Let us quickly create a user by the below code.

from django.contrib.auth.models import User

user = User.objects.create_user( 
        first_name="Clark", 
        last_name="Kent", 
        username="clark123", 
        password="clark_pass", 
        email="clarkkent@example.com" )

Now to add permissions user we need to import User, Permission and ContentType models.

from django.contrib.auth.models import User, Permission
from django.contrib.contenttypes.models import ContentType
from permissions.models import Team

# Get Content Type for Model 
content_type = ContentType.objects.get_for_model(Team, for_concrete_model=True)

# Get permission `can_edit_team` for Model.
can_edit_team = Permission.objects.filter(content_type=content_type, codename="can_edit_team").first()

# Add Permission to User
user.user_permissions.add(can_edit_team)

Check if the user has permission

Now we know how to add permissions to users and to check the permission of the user for the given model use method has_perm and has_perms.

has_perm

The has_perm is used to check single permission. We must pass app_label with the codename. Takes a string as an argument and returns a boolean value.

user.has_perm('permissions.can_edit_team')
  • permissions: Is app_label or you can give the app name if app_label not specified in the model.
  • can_edit_team: Is a codename for auth_permission.The codename must unique throughout the application.

has_perms

The has_perms checks the permission for multiple permission codenames. Takes list as an argument and returns a boolean value.

user.has_perm([ 'permissions.can_edit_team', 'permissions.add_team'] )
If the user’s attribute is_superuser is True than all permissions will return True.

Working with Authentication Groups

Assigning permissions to every user is not an efficient task to simplify this process Django provides Group the model were we create groups and add permissions to that group.
Then users are assigned to that group. A single user may have multiple groups.

Create a Group

To create Group import Model Group from from django.contrib.auth.models import Group.
Let us name our new group as staff.

staff_group = Group.objects.filter(name="staff").first()

Add permissions to Group

We’ll add permissions to the staff group.

#add Permissions to Group

permission_codename = ['can_create_team', 'can_view_team'];

for permission in permission_codename:
    perm  = Permission.objects.filter(codename=permission).first()
    staff_group.permissions.add(perm) # added permissions to group

Assign Group to user

Get user from User model and assign staff_group to user.

user.groups.add(staff_group)  

Check if a user in the group has permission

We have defined a function that checks if the user has permission under any group. It takes three arguments and they are user, model, and perm and all these return a Boolean value.

def user_has_group_permission(user, model, perm):

    is_authenticated = False

    content_type = ContentType.objects.get_for_model(model, for_concrete_model=True)

    groups = Group.objects.filter( user=user ).prefetch_related('permissions')

    permission = Permission.objects.filter( content_type_id=content_type, codename=perm ).first()

    for group in groups:
        if group.permissions.filter(id=permission.id).first():
            is_authenticated=True
        else:
            is_authenticated=False
            break

    return is_authenticated

In Function user_has_group_permission.

  • The content_type gets the model name from the database.
  • The groups contain a list of groups that are assigned to the user.
  • The permission contains the current requested permission i.e perm argument and gets its object.
  • Inside for-loop if group.permissions.filter(id=permission.id).first() has any permission then is_authenticated is set to True and if does not have an object that is set to False and exists from for loop.

To check if the user has permission for a list of permissions.

def user_has_group_permissions(user, model, perms):
    is_authenticated = False

    for perm in perms:
        is_authenticated = user_has_group_permission(user, model, perm)
        if not is_authenticated:
            is_authenticated=False
            break

    return is_authenticated

The Function user_has_group_permissions is used for checking multiple permissions.

For official documentation visit Django Docs.

Conclusion

So we have come to the conclusion part of our Easiest way to authorize users using Django Permissions, Roles, and Groups for Beginners post. For queries comment below and we’ll reach you soon.

Related Posts

Summary
Review Date
Reviewed Item
Easiest way to authorize users using Django Permissions, Roles, and Groups for Beginners
Author Rating
51star
1star1star1star1star
Software Name
Django Web Framework
Software Name
Windows Os, Mac Os, Ubuntu Os
Software Category
Web Development