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

在Django中实现可配置权限与角色的最优方案探讨

Django可配置角色与权限实现方案

针对你的需求,最优方案是基于Django用户系统扩展,自定义角色(Role)与模块权限(ModulePermission)模型,实现模块-任务级别的灵活权限管控,同时自行开发管理界面替代Django Admin。以下是具体实现思路与代码示例:

1. 核心模型设计

脱离Django自带Permission与Group的模型绑定限制,通过自定义模型实现任意模块与任务的权限定义,支持角色与权限、用户与角色的多对多关联:

from django.db import models
from django.contrib.auth.models import AbstractUser

# 自定义用户模型,关联多个角色
class CustomUser(AbstractUser):
    roles = models.ManyToManyField('Role', blank=True, related_name='users')

    class Meta:
        verbose_name = '用户'
        verbose_name_plural = '用户'

# 角色模型,可绑定多个权限
class Role(models.Model):
    name = models.CharField(max_length=100, unique=True, verbose_name='角色名称')
    description = models.TextField(blank=True, verbose_name='角色描述')
    permissions = models.ManyToManyField('ModulePermission', blank=True, related_name='roles', verbose_name='关联权限')

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = '角色'
        verbose_name_plural = '角色'

# 模块权限模型,定义具体模块的可执行任务
class ModulePermission(models.Model):
    MODULE_CHOICES = [
        ('user_management', '用户管理'),
        ('content_management', '内容管理'),
        ('order_management', '订单管理'),
        # 可根据业务需求扩展更多模块
    ]
    module = models.CharField(max_length=50, choices=MODULE_CHOICES, verbose_name='所属模块')
    task = models.CharField(max_length=100, verbose_name='权限任务')  # 如"add_user", "edit_content", "approve_order"
    description = models.TextField(blank=True, verbose_name='权限描述')

    class Meta:
        unique_together = ('module', 'task')  # 确保同一模块下任务唯一
        verbose_name = '模块权限'
        verbose_name_plural = '模块权限'

    def __str__(self):
        return f"{self.get_module_display()} - {self.task}"

关键配置:在settings.py中指定自定义用户模型:

AUTH_USER_MODEL = 'your_app_name.CustomUser'

2. 权限校验逻辑

封装统一的权限校验函数与装饰器,方便在视图和模板中快速使用:

工具函数与视图装饰器

from django.contrib.auth.decorators import user_passes_test

def has_permission(user, module, task):
    """检查用户是否拥有指定模块的任务权限"""
    if user.is_superuser:
        return True  # 超级用户默认拥有所有权限
    return user.roles.filter(
        permissions__module=module,
        permissions__task=task
    ).exists()

def permission_required(module, task):
    """视图装饰器:校验用户权限"""
    return user_passes_test(lambda u: has_permission(u, module, task))

模板过滤器

为了在模板中直接判断权限,添加自定义模板过滤器:

from django import template
from .utils import has_permission

register = template.Library()

@register.filter(name='has_perm')
def has_permission_filter(user, perm_string):
    """模板中用法:{{ request.user|has_perm:"module,task" }}"""
    module, task = perm_string.split(',')
    return has_permission(user, module.strip(), task.strip())

3. 角色与权限管理界面

自行开发CRUD视图与模板,实现角色创建、权限分配、用户角色分配功能:

表单定义

from django import forms
from .models import Role, ModulePermission, CustomUser

class RoleForm(forms.ModelForm):
    class Meta:
        model = Role
        fields = ['name', 'description']
        widgets = {
            'description': forms.Textarea(attrs={'rows': 3})
        }

class RolePermissionForm(forms.ModelForm):
    class Meta:
        model = Role
        fields = ['permissions']
        widgets = {
            'permissions': forms.CheckboxSelectMultiple  # 多选框展示权限选项
        }

class UserRoleForm(forms.ModelForm):
    class Meta:
        model = CustomUser
        fields = ['roles']
        widgets = {
            'roles': forms.CheckboxSelectMultiple
        }

核心视图示例

from django.shortcuts import render, redirect, get_object_or_404
from .forms import RoleForm, RolePermissionForm, UserRoleForm
from .models import Role, CustomUser

# 创建角色
def create_role(request):
    if request.method == 'POST':
        form = RoleForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('role_list')
    else:
        form = RoleForm()
    return render(request, 'roles/create_role.html', {'form': form})

# 为角色分配权限
def assign_permissions(request, role_id):
    role = get_object_or_404(Role, id=role_id)
    if request.method == 'POST':
        form = RolePermissionForm(request.POST, instance=role)
        if form.is_valid():
            form.save()
            return redirect('role_detail', role_id=role.id)
    else:
        form = RolePermissionForm(instance=role)
    return render(request, 'roles/assign_permissions.html', {'form': form, 'role': role})

# 为用户分配角色
def assign_user_roles(request, user_id):
    user = get_object_or_404(CustomUser, id=user_id)
    if request.method == 'POST':
        form = UserRoleForm(request.POST, instance=user)
        if form.is_valid():
            form.save()
            return redirect('user_detail', user_id=user.id)
    else:
        form = UserRoleForm(instance=user)
    return render(request, 'users/assign_roles.html', {'form': form, 'user': user})

模板示例(create_role.html)

<h2>添加新角色</h2>
<form method="post" class="role-form">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn">保存角色</button>
</form>
<a href="{% url 'role_list' %}" class="back-link">返回角色列表</a>

4. 实际使用示例

视图中校验权限

from .utils import permission_required

@permission_required('content_management', 'edit_content')
def edit_content(request, content_id):
    # 编辑内容的业务逻辑
    ...

模板中控制元素显示

{% if request.user|has_perm:"order_management,approve_order" %}
    <button class="approve-btn">审批订单</button>
{% endif %}

优化建议

  • 权限缓存:高并发场景下,可在用户登录时将其权限列表缓存至Redis或Django缓存,角色/权限变更时清除对应缓存,减少数据库查询。
  • 批量操作:在管理界面添加批量分配角色、批量修改权限的功能,提升管理效率。
  • 权限继承:若需角色层级,可在Role模型中添加parent_role字段,实现权限继承逻辑。

内容的提问来源于stack exchange,提问作者Muhammadoufi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 18:04:58