Search code examples
djangodjango-users

Permissions except for a group


In the query below, I get a list of all permissions.

routines = (
    Permission.objects.select_related("content_type")
    .values("id", "name", "content_type__app_label", "content_type__model", )
    .order_by("content_type__app_label")
)

Query return:

accounts | accountsroutine | Can add accounts routine 
accounts | accountsroutine | Can change accounts routine 
accounts | accountsroutine | Can delete accounts routine 
accounts | accountsroutine | Can view accounts routine 

I need to change this query to exclude from it the permissions already granted to a particular group. How to make?


Solution

  • Resolved using raw query,with clause NOTING IN.

    Example:

        # Get permissions group
        group = Group.objects.get(id=pk)
        permissions = (
            group.permissions.all()
            .values("id")
        )
    
        # Make list with group permission id
        selected = []
        for permission in permissions:
            selected.append(permission["id"])
        selected = tuple(selected)
    
        # Sql to get routines and permissions
        sql = """
                SELECT 
                    accounts_routine.accounts_routine_id,
                    accounts_routine.name AS routine_name,
                    auth_permission.id,
                    auth_permission.name AS permission_name
                FROM 
                    accounts_routine 
                INNER JOIN
                    django_content_type
                ON 
                    accounts_routine.django_content_type_id = django_content_type.id
                inner join
                    auth_permission
                on
                    auth_permission.content_type_id = django_content_type.id
            """
    
        # Not list permissions authorized
        if len(selected) == 1:
            sql = """{} {} {}""".format(
                sql,
                "WHERE auth_permission.id != ",
                selected[0]
            )
        elif len(selected) > 1:
            sql = """{} {} {}""".format(
                sql,
                "WHERE auth_permission.id NOT IN",
                selected
            )
    
        # Remove extra space
        sql = sql.replace("  ", " ")
    
        # Get routines
        routines = AccountsRoutine.objects.raw(sql)