Django ListView通过关联模型查询招聘专员管辖员工的实现问题
Django多模型关联查询ListView实现方案
中间表必要性说明
你构思的AssignedOffice中间表是必须的,因为Recruiter和Office属于多对多关系,需要中间表存储二者的关联映射。
代码优化调整
1. 中间表可选优化
你原有中间表关联的是UserProfile,如果业务逻辑上Recruiter的organization字段和UserProfile一一对应,可以直接沿用原中间表,也可以调整为直接关联Recruiter让映射更直观:
class AssignedOffice(models.Model): recruiter = models.ForeignKey(Recruiter, on_delete=models.CASCADE, related_name="assigned_offices") esa_office = models.ForeignKey(Office, on_delete=models.CASCADE, related_name="assigned_recruiters")
2. ListView查询逻辑重写
核心逻辑为:先获取当前登录用户对应的招聘专员,再查询该招聘专员所有分配的办公点,最后过滤出这些办公点下的所有招聘对象,用distinct()去重避免重复数据:
class MyESA(LoginRequiredMixin, ListView): template_name = "recruits/recruits_list.html" paginate_by = 20 model = Recruit context_object_name = 'recruits' def get_queryset(self): # 获取当前登录用户对应的招聘专员 current_recruiter = self.request.user.recruiter # 若使用优化后的中间表(关联Recruiter),用此代码获取关联办公点ID assigned_office_ids = current_recruiter.assigned_offices.values_list("esa_office_id", flat=True) # 若沿用你原有中间表(关联UserProfile),把上一行替换为下方代码即可 # assigned_office_ids = AssignedOffice.objects.filter( # user=current_recruiter.organization # ).values_list("esa_office_id", flat=True) # 过滤招聘对象,保留原有probablity过滤条件,distinct去重 queryset = Recruit.objects.filter( probablity=1, officeid_id__in=assigned_office_ids ).distinct() return queryset
额外优化建议
- Recruit模型的
officeid外键建议重命名为office,避免和Office表的officeid字段混淆,更符合Django命名规范 - 可给关联字段添加数据库索引,提升大数量场景下的查询效率
- 如果不存在同一个招聘对象归属多个办公点的场景,可以去掉
distinct()减少查询开销
内容的提问来源于stack exchange,提问作者Ryanrex
相关产品推荐
相关产品推荐

