You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:09:05