如何用django-rules基于项目团队控制Task行级权限?
使用django-rules实现用户仅查看所属团队项目关联Task的权限控制
我来帮你一步步搞定这个权限控制需求,核心思路就是通过用户所属的组,匹配Task关联Project的team字段,结合django-rules把这个逻辑封装成可复用的权限规则。咱们从模型确认到规则落地一步步来:
1. 先确认模型结构(适配你的场景)
首先我假设你的模型大概是这样的(如果和你的实际代码有出入,调整对应字段即可):
# your_app/models.py from django.db import models from django.contrib.auth.models import Group class Project(models.Model): name = models.CharField(max_length=100) # 关联auth_group,对应团队 team = models.ForeignKey(Group, on_delete=models.CASCADE, related_name="projects") # 其他业务字段... class Task(models.Model): project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="tasks") title = models.CharField(max_length=100) # 其他业务字段...
2. 配置django-rules
首先确保你已经安装并启用了django-rules:
- 安装:
pip install django-rules - 加到INSTALLED_APPS:
# settings.py INSTALLED_APPS = [ # 已有的app... 'rules', ]
3. 定义权限规则
在你的app下新建rules.py文件,编写核心的权限判断逻辑:
# your_app/rules.py import rules # 定义判断谓词:用户是否能查看该Task @rules.predicate def is_task_in_user_team(user, task=None): # 如果没有传入task(比如列表视图场景),先返回False if not task: return False # 获取用户所属的所有组 user_groups = user.groups.all() # 判断Task关联的Project的team是否在用户的组列表中 return task.project.team in user_groups # 可选:添加超级用户豁免规则 @rules.predicate def is_superuser(user): return user.is_superuser # 组合规则:超级用户 或 任务属于用户所在团队 can_view_task = is_superuser | is_task_in_user_team # 注册权限:将规则绑定到view_task权限上 rules.add_perm('your_app.view_task', can_view_task)
4. 在视图中应用权限
基于类的视图(推荐)
使用rules.contrib.views.PermissionRequiredMixin做权限校验,同时在列表视图中过滤QuerySet,确保只返回用户有权限查看的Task:
# your_app/views.py from django.views.generic import ListView, DetailView from rules.contrib.views import PermissionRequiredMixin from .models import Task class TaskListView(PermissionRequiredMixin, ListView): model = Task permission_required = 'your_app.view_task' def get_queryset(self): # 过滤出用户所在团队的项目对应的Task user_groups = self.request.user.groups.all() return Task.objects.filter(project__team__in=user_groups) class TaskDetailView(PermissionRequiredMixin, DetailView): model = Task permission_required = 'your_app.view_task'
函数视图
使用rules.decorators.permission_required装饰器,自动校验单个Task的权限:
# your_app/views.py from rules.decorators import permission_required from .models import Task @permission_required('your_app.view_task', fn=lambda request, task_id: Task.objects.get(id=task_id)) def task_detail(request, task_id): task = Task.objects.get(id=task_id) # 你的视图逻辑...
5. 模板中判断权限
如果需要在模板中控制单个Task的显示,可以直接使用django的权限模板标签:
<!-- your_app/templates/your_app/task_detail.html --> {% load rules %} {% if perms.your_app.view_task task %} <h3>{{ task.title }}</h3> <p>所属项目:{{ task.project.name }}</p> <!-- 其他Task内容 --> {% else %} <div class="alert alert-warning">你没有权限查看这个任务</div> {% endif %}
关键逻辑说明
整个流程的核心是:
- 获取用户的所有所属组
- 匹配Task→Project→team字段是否在用户组列表中
- 通过django-rules把这个逻辑封装成可复用的权限,在视图、模板中统一调用
这样就能实现像John Smith属于Team X组时,只能查看Team X关联Project下的Task啦。
内容的提问来源于stack exchange,提问作者OverflowingTheGlass
相关产品推荐
相关产品推荐

