This page looks best with JavaScript enabled

Permission Control in Django

1. Django Built-in Permission Management

1.1 Permission Categories

  1. Permission
    Used to define User A’s permission on Task.
  2. User
    If User A has permission on Model B, then User A has the corresponding permission on all instances in Model B. The user_permission field of the User object is used to manage the user’s permissions. Use assign_perm to assign permissions to a User.
  3. Group
    If Group C has permission on Model B, then all Users belonging to Group C have the corresponding permission on Model B.

1.2 Configuration and Implementation

  1. Permission

After Django defines each model, by default it adds three permissions for that model: add, change, and delete. Custom permissions can be added manually when defining the model:

1
2
3
4
5
6
7
8
class Task(models.Model):
    ...
    class Meta:
        permissions = (
            ("view_task", "Can see available tasks"),
            ("change_task_status", "Can change the status of tasks"),
            ("close_task", "Can remove a task by setting its status as closed"),
        )

Every permission is an instance of the django.contrib.auth.Permission type, which contains three fields: name, codename, and content_type. content_type reflects which model the permission belongs to; codename is like view_task above and is used when checking permissions in code logic; name is the description of the permission, and it is what is displayed by default when a permission is printed to the screen or a page.

Creating a custom permission in a model can be understood, from the perspective of system development, as creating a built-in permission of the system. If a requirement involves creating custom permissions while the user is using the system, then use the following approach:

1
2
3
4
5
6
from myapp.models import Post
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType

content_type = ContentType.objects.get_for_model(Post)
permission = Permission.objects.create(codename='can_publish', name='Can Publish Posts', content_type=content_type)
  1. User and Group

Django’s built-in permission authentication is bound into django.contrib.auth, and the Permission model in auth in turn depends on contenttypes.

1
2
3
4
INSTALLED_APPS = (
    'django.contrib.auth'
    'django.contrib.contenttypes'
)
1
manage.py syncdb

The following tables are then created in the database:

  • auth_group
  • auth_group_permissions
  • auth_permission
  • auth_user
  • auth_user_groups
  • auth_user_user_permissions

From the table names you can see that auth_user has two external relationships, groups and user_permissions.

1
manage.py  shell

The command above lets the interpreter load the settings file of the Django project and enter a mode in which objects in the project can be operated on directly.

1
2
3
4
>>> from django.contrib.auth.models import User
>>> A  = User.objects.create_user('name','nameg@email.com','password')
>>> A.groups = [group_list]
>>> A.user_permissions = [permission_list]

The groups and user_permissions of every object have three methods for modifying permissions.

A.groups.[add|remove|clear()]
A.user_permissions.[add|remove|clear()]

1.3 Usage

There are usually two ways to use it,

  • Check by calling the has_perm() function inside a View function.
    A/Group.has_perm(‘applabel.task’) is used to check a user’s/group’s permission. In addition, A.get_all_permissions() lists all of a user’s permissions, and A.get_group_permissions() lists the permissions of the groups the user belongs to.
  • Use a decorator before the View function.
    @permission_required(‘applabel.task’)

2. Django-guardian

Take the common multi-author blog system as an example: each blog post is an object. The Django built-in permission control approach described above cannot achieve object-level control. Django does not provide object-level permission control, but it left an interface in its architecture. django-guardian is a very popular object-level permission control component. Object Permission is a permission mechanism at object granularity that allows authorization for each specific object. If the read/write permission on object b is granted to User A, then User A has read/write permission only on object b, and cannot operate on other objects of the same kind.

2.1 Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14

pip install django-guardian

INSTALLED_APPS = (
    'guardian',
)

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend', # this is default
    'guardian.backends.ObjectPermissionBackend',
]
#如果要支持匿名用户AnoymousUser的Object级别的权限控制,要在settings中加入
#匿名用户权限控制
ANONYMOUS_USER_ID = -1
1
python manage syncdb

The following tables are then created in the database:

  • guardian_groupobjectpermission
  • guardian_userobjectpermission

2.2 Usage

  1. Editing permissions

guardian.shortcuts.assign(perm, user_or_group, obj=None) add a permission
guardian.shortcuts.remove_perm(perm,user_or_group=None, obj=None) remove a permission
guardian.shortcuts.get_perms(user_or_group,obj) get all permissions

  • perm: this parameter is a string representing a permission, and its format must be app.perm_codename or perm_codename. However, if the third parameter is None, it must be in app.perm_codename format. It is therefore still recommended to use the app.perm_codename format uniformly. Note that app is not the full path of the app, but the module name at the last level. This differs from the full app path in INSTALL_APP, so if your app module has more than one level, pay close attention here.
  • user_or_group: this parameter is a User or Group type object.
  • obj: this parameter is the related object. This parameter can be omitted; if omitted, the Model permission is granted.
  1. Checking permissions
  • user.has_perm('app.view_task') #检测权限
  • ObjectPermissionChecker(request.user).has_perm('app.view_task', task)
  • guardian.decorators.permission_required()

3. References


微信公众号
WRITTEN BY
微信公众号