如何在Django薪资详情页关联展示对应员工的出勤记录?
如何在薪资详情页展示对应员工的出勤记录
嘿,这事儿不难搞定,咱们利用Django的模型关联特性就能实现,我给你两种方案,从快速实现到性能优化的都有:
方案1:直接在模板里通过关联关系调用
你的Salary模型和Employee是关联的,而Employee又通过related_name='attendance'和Attendance绑定了关系,所以在salary_detail.html里,直接通过薪资实例找到员工,再遍历它的出勤记录就行:
<h3>对应员工的出勤记录</h3> <ul> {% for attendance in salary_detail.employee.attendance.all %} <li>出勤日期:{{ attendance.date }}</li> {% empty %} <li>该员工暂无对应出勤记录</li> {% endfor %} </ul>
不过要注意,这种写法虽然简单,但如果页面访问量高的话,每次渲染都会额外触发一次数据库查询来获取出勤记录,可能会出现N+1查询的性能问题。如果你的系统数据量不大,这个方案完全够用;如果要追求性能,推荐下面的优化方案。
方案2:在View中预取关联数据(推荐)
我们可以重写DetailView的get_context_data方法,提前把需要的出勤记录查好放到上下文里,这样就能避免额外的数据库查询:
修改你的views.py代码:
class Salary(DetailView): context_object_name = 'salary_detail' model = models.Salary template_name = 'system/salary_detail.html' def get_context_data(self, **kwargs): # 先获取默认的上下文内容 context = super().get_context_data(**kwargs) # 从当前薪资实例拿到对应的员工 employee = self.object.employee # 获取该员工的所有出勤记录 attendance_list = employee.attendance.all() # 把出勤记录添加到上下文,供模板使用 context['attendance_list'] = attendance_list return context
然后在salary_detail.html里直接用这个上下文变量:
<h3>对应员工的出勤记录</h3> <ul> {% for attendance in attendance_list %} <li>出勤日期:{{ attendance.date }}</li> {% empty %} <li>该员工暂无对应出勤记录</li> {% endfor %} </ul>
如果想进一步压榨性能,还可以在获取薪资对象的时候就预取关联的员工和出勤记录,减少数据库查询次数,修改get_queryset方法:
class Salary(DetailView): context_object_name = 'salary_detail' model = models.Salary template_name = 'system/salary_detail.html' def get_queryset(self): # 预取关联的员工,以及员工的出勤记录,一次性把需要的数据都查出来 return super().get_queryset().select_related('employee').prefetch_related('employee__attendance') def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 现在直接从已预取的对象中拿数据,不用再发起新查询 context['attendance_list'] = self.object.employee.attendance.all() return context
这样整个页面只会发起1-2次数据库查询,性能会好很多,尤其是数据量大的时候。
内容的提问来源于stack exchange,提问作者Budi Gunawan
相关产品推荐
相关产品推荐

