Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create groups and assign permission during project setup in django?

Tags:

python

django

I know I can create user groups and assign permission to them from the admin area in a django project. I can also create a group and assign permission to it by importing Group and Permission model from django's auth module.

What I want to know if there is any way I can create group and assign permission to them when I set up the project. So, if I have types of users, Admin, Developer, Tester and Project Manager. They are basically user groups which would have different permission level. I did not customize the User model and only can differentiate by the groups they are assigned to. So is there a way to create these groups and assign required permission to them like when permissions are created for admin when I run python manage.py migrate?

like image 478
Sayantan Das Avatar asked Mar 12 '17 04:03

Sayantan Das


People also ask

How do I add permissions to a Django model?

Add Permissions to a Group If you are using AbstractUser in Django, you must add AUTH_USER_MODEL = 'YourAppName. YourClassName' . This way, you are telling Django to use our custom user model instead of the default one. The code below should go in your admin.py file so that you can see your user model.


2 Answers

You can define a post_migrate signal to create required User and Group model instances if they don't exist already.

When you create an application in using python manage.py startapp <app_name>, it creates an AppConfig class in apps.py file.

You can specify which signal to call in AppConfig class definition. Say the signal is called populate_models. In that case, modify AppConfig to look like following:

from django.apps import AppConfig
from django.db.models.signals import post_migrate

class AppConfig(AppConfig):
    name = 'app'

    def ready(self):
        from .signals import populate_models
        post_migrate.connect(populate_models, sender=self)

And in signals.py define the populate_models function.

def populate_models(sender, **kwargs):
    from django.contrib.auth.models import User
    from django.contrib.auth.models import group
    # create groups
    # assign permissions to groups
    # create users
like image 108
narendra-choudhary Avatar answered Oct 03 '22 15:10

narendra-choudhary


According to @narenda-choudhary and @Rolando Cruz answer,

Here is the code for adding all existing permissions of an app under a Group. For exemple if you have App1 and App2, and you want to automatically create 2 groups named app1 and app2 containing permissions to the models of each app (respectively), try this :

For App1 on apps.py :

from django.apps import AppConfig
from django.db.models.signals import post_migrate

class App1Config(AppConfig):
    name = 'app1'

    def ready(self):
        from .signals import populate_models
        post_migrate.connect(populate_models, sender=self)

Create a signals.py file that contains :

def populate_models(sender, **kwargs):
    from django.apps import apps
    from .apps import App1Config
    from django.contrib.auth.models import Group, Permission
    from django.contrib.contenttypes.models import ContentType

    group_app, created = Group.objects.get_or_create(name=App1Config.name)

    models = apps.all_models[App1Config.name]
    for model in models:
        content_type = ContentType.objects.get(
            app_label=App1Config.name,
            model=model
        )
        permissions = Permission.objects.filter(content_type=content_type)
        group_app.permissions.add(*permissions)

Do the same for App2

Then assign users to their groups.

For usage :

Create a file called permissions.py on each app and add :

from .apps import App1Config

def is_in_group_app1(user):
    return user.groups.filter(name=App1Config.name).exists() 

In views.py use :

from django.contrib.auth.decorators import login_required, user_passes_test
from .permissions import is_in_group_app1

@login_required(login_url='where_to_redirect')
@user_passes_test(is_in_group_app1) 
def myview(request):
    # Do your processing

For CBV :

@method_decorator(user_passes_test(is_in_group_app1), name='dispatch')
class LogListView(ListView):
    """ Displays all logs saved on App1 """
    model= Logger.objects.order_by('-date_created')

Create a folder named templatestag and subfolder app1 and a has_perms.py file :

from django import template
from app1.permissions import is_in_group_app1
register = template.Library()

@register.filter
def has_perms(user):
    return is_in_group_app1(user)

In your template :

{% load has_perms %}

{% if request.user|has_perms %}
    <li class="nav-item">
        <a href="{% url 'app1:log' %}" class="nav-link">
            <i class="icon-history"></i>
            <span data-i18n="nav.dash.main">App1 Log</span>
        </a>
    </li>
{% endif %}

It took me a while to find all this process, so if it can help others :

Enjoy ;) !

like image 42
HamzDiou Avatar answered Oct 03 '22 14:10

HamzDiou