如何在Django Guardian中移除用户全部权限以重置后分配新对象权限
实现方案
本方案基于Django生态常用的对象级权限扩展库django-guardian实现,如果你已自行实现对象权限管控逻辑,仅需调整核心的权限删除、分配逻辑即可。
1. 重置指定用户对目标学校的所有关联对象权限
先批量移除用户对目标学校、关联年级、关联学生记录的全部权限:
from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from guardian.shortcuts import remove_perm, assign_perm from .models import School, Grade, StudentRecord def reset_user_school_permissions(user: User, target_school: School): """ 重置用户对指定学校及所有关联对象的全部增删改查权限 """ # 获取目标学校关联的所有对象 related_grades = Grade.objects.filter(school=target_school) related_records = StudentRecord.objects.filter(school=target_school) # Django默认的四类基础权限前缀 base_perm_actions = ['add', 'change', 'view', 'delete'] # 移除学校本身的权限 school_ct = ContentType.objects.get_for_model(School) for action in base_perm_actions: perm_codename = f"{action}_{school_ct.model}" remove_perm(perm_codename, user, target_school) # 移除所有关联年级的权限 grade_ct = ContentType.objects.get_for_model(Grade) for grade in related_grades: for action in base_perm_actions: perm_codename = f"{action}_{grade_ct.model}" remove_perm(perm_codename, user, grade) # 移除所有关联学生记录的权限 record_ct = ContentType.objects.get_for_model(StudentRecord) for record in related_records: for action in base_perm_actions: perm_codename = f"{action}_{record_ct.model}" remove_perm(perm_codename, user, record)
2. 给用户分配目标学校的所有关联对象权限
重置完成后调用分配函数完成权限赋值:
def assign_user_school_permissions(user: User, target_school: School): """ 给用户分配指定学校及所有关联对象的全部增删改查权限 """ related_grades = Grade.objects.filter(school=target_school) related_records = StudentRecord.objects.filter(school=target_school) base_perm_actions = ['add', 'change', 'view', 'delete'] # 分配学校本身的权限 school_ct = ContentType.objects.get_for_model(School) for action in base_perm_actions: perm_codename = f"{action}_{school_ct.model}" assign_perm(perm_codename, user, target_school) # 分配所有关联年级的权限 grade_ct = ContentType.objects.get_for_model(Grade) for grade in related_grades: for action in base_perm_actions: perm_codename = f"{action}_{grade_ct.model}" assign_perm(perm_codename, user, grade) # 分配所有关联学生记录的权限 record_ct = ContentType.objects.get_for_model(StudentRecord) for record in related_records: for action in base_perm_actions: perm_codename = f"{action}_{record_ct.model}" assign_perm(perm_codename, user, record)
3. 更换管理员的完整调用示例
# 示例:将id为1的学校管理员从old_manager更换为new_manager target_school = School.objects.get(id=1) old_manager = User.objects.get(username="old_manager") new_manager = User.objects.get(username="new_manager") # 先清空旧管理员的对应权限 reset_user_school_permissions(old_manager, target_school) # 给新管理员分配对应权限 assign_user_school_permissions(new_manager, target_school)
注意:你示例中
StudentRecord模型的school外键字段related_name和Grade模型的重复,均为grades会触发字段冲突,建议修改为related_name='student_records'。
内容的提问来源于stack exchange,提问作者Poula Adel
相关产品推荐
相关产品推荐

