Django关联查询:如何筛选登录负责人管辖部门的Incident数据
Django ORM实现部门领导管辖组下未删除事件查询
模型关系梳理
假设你的模型结构大致如下(可根据实际关联字段调整):
from django.contrib.auth.models import User from django.db import models class Department(models.Model): name = models.CharField(max_length=100) leader = models.ForeignKey(User, on_delete=models.CASCADE, related_name='managed_departments') class Group(models.Model): name = models.CharField(max_length=100) department = models.ForeignKey(Department, on_delete=models.CASCADE, related_name='groups') class Incident(models.Model): title = models.CharField(max_length=200) group = models.ForeignKey(Group, on_delete=models.CASCADE, related_name='incidents') is_deleted = models.BooleanField(default=False)
ORM查询实现
核心是通过跨表链式过滤,从当前登录用户(部门领导)关联到管辖部门,再到部门下的组,最后筛选未删除的事件:
基础链式过滤写法
在视图中直接利用request.user做关联过滤:
# views.py from django.contrib.auth.decorators import login_required from .models import Incident @login_required def get_managed_incidents(request): # 获取当前领导管辖组下的未删除事件 managed_incidents = Incident.objects.filter( group__department__leader=request.user, is_deleted=False ).select_related('group__department') # 预加载关联表,避免N+1查询 # 后续业务处理(序列化、返回响应等) return ...
对应原生SQL映射
这个ORM查询和你提供的SQL逻辑完全匹配,等价于:
SELECT * FROM incident JOIN `group` ON incident.group_id = `group`.id JOIN department ON `group`.department_id = department.id WHERE department.leader_id = {当前用户ID} AND incident.is_deleted = 0;
反向关联简化写法
如果Department的leader字段设置了related_name='managed_departments',也可以从用户端反向查询:
managed_incidents = Incident.objects.filter( group__department__in=request.user.managed_departments.all(), is_deleted=False )
这种写法逻辑更直观:先取用户管理的所有部门,再过滤这些部门下组的事件。
关键优化与注意事项
- 登录校验:用
@login_required装饰视图,确保只有登录用户能访问 - 性能优化:使用
select_related预加载关联的Group和Department,避免多次数据库查询 - 权限校验:如果需要更严谨的权限控制,可以自定义权限类,验证当前用户确实是对应部门的领导
内容的提问来源于stack exchange,提问作者mir_kol
相关产品推荐
相关产品推荐

