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

如何在Django中建立经理与员工关联,实现数据隔离?

解决方案

1. 基础修正:创建员工时绑定当前经理

首先要确保经理创建员工账号时,自动将当前登录的经理(其User实例)关联到员工的manager字段,这是建立关联的核心前提。

函数视图实现示例

from django.contrib.auth.decorators import login_required
from django.shortcuts import render, redirect
from .models import Employee, User

@login_required
def create_employee(request):
    if request.method == 'POST':
        # 处理表单数据,创建员工的User账号
        username = request.POST.get('username')
        email = request.POST.get('email')
        user = User.objects.create_user(username=username, email=email)
        # 将当前登录的经理绑定为该员工的直属上级
        Employee.objects.create(user=user, manager=request.user)
        # 执行发送设置密码邮件的逻辑...
        return redirect('employee_list')
    return render(request, 'create_employee.html')

类视图(CreateView)实现示例

from django.views.generic.edit import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Employee

class EmployeeCreateView(LoginRequiredMixin, CreateView):
    model = Employee
    fields = ['user']  # 根据实际表单需求调整字段

    def form_valid(self, form):
        # 手动为员工绑定当前登录的经理
        form.instance.manager = self.request.user
        return super().form_valid(form)

2. 过滤员工列表:仅展示当前经理的下属

在员工列表视图中,通过过滤查询集,只保留与当前登录用户关联的员工:

函数视图实现示例

@login_required
def employee_list(request):
    # 仅查询当前经理创建的员工
    employees = Employee.objects.filter(manager=request.user)
    return render(request, 'employee_list.html', {'employees': employees})

类视图(ListView)实现示例

from django.views.generic.list import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
from .models import Employee

class EmployeeListView(LoginRequiredMixin, ListView):
    model = Employee
    template_name = 'employee_list.html'

    def get_queryset(self):
        # 重写查询集,仅返回当前经理的下属
        return Employee.objects.filter(manager=self.request.user)

3. 模型逻辑优化(可选)

当前Employee的manager字段关联的是User模型,你可以改为关联Manager模型,这样能从数据库层面确保只有经理能成为员工的上级,逻辑更严谨:

修改后的Employee模型:

class Employee(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    # 关联到Manager模型而非User
    manager = models.ForeignKey(Manager, related_name='employees', on_delete=models.CASCADE)
    is_employee = models.BooleanField(default=True)
    
    def __str__(self):
            return self.user.username

对应的视图代码也要同步调整:

  • 创建员工时:
# 函数视图中
manager_instance = Manager.objects.get(user=request.user)
Employee.objects.create(user=user, manager=manager_instance)

# 类视图中
def form_valid(self, form):
    form.instance.manager = Manager.objects.get(user=self.request.user)
    return super().form_valid(form)
  • 查询员工列表时:
# 函数视图
employees = Employee.objects.filter(manager__user=request.user)

# 类视图get_queryset方法
return Employee.objects.filter(manager__user=self.request.user)

4. 权限加固:防止越权操作

为避免经理通过URL直接访问不属于自己的员工页面,需要在详情、编辑、删除视图中添加权限校验:

函数视图权限校验示例

@login_required
def edit_employee(request, pk):
    employee = Employee.objects.get(pk=pk)
    # 校验当前用户是否是该员工的直属经理
    if employee.manager != request.user:
        # 返回权限拒绝页面或重定向到列表页
        return redirect('employee_list')
    # 后续编辑逻辑...

类视图自定义权限Mixin示例

from django.core.exceptions import PermissionDenied

class EmployeePermissionMixin:
    def get_object(self, queryset=None):
        obj = super().get_object(queryset)
        # 校验当前用户是否有权限操作该员工
        if obj.manager != self.request.user:
            raise PermissionDenied
        return obj

class EmployeeUpdateView(LoginRequiredMixin, EmployeePermissionMixin, UpdateView):
    model = Employee
    fields = ['...']  # 根据实际需求设置可编辑字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 13:18:17