Django考勤系统开发问题:如何正确检索并显示当前在场用户的信息
问题分析与解决方案
首先,核心问题出在视图层的查询方式和模板层的变量引用不匹配,导致无法正确显示用户名。下面一步步拆解并解决:
1. 为什么用户名显示不出来?
你在视图中使用了.values('user__username')来查询数据:
p = Paginator(is_Present.objects.filter(date=today).filter(is_present=True).select_related('user').values('user__username'), 5)
.values()方法返回的是字典列表,每个字典的键是你指定的user__username,而不是is_Present模型实例。但你的模板中试图访问{{ user.username }},这就会找不到对应的值——因为字典里没有username这个键,只有user__username。
另外,你用datetime.today()作为过滤条件,它返回的是datetime类型(包含时分秒),而你的is_Present.date是DateField(仅日期),虽然Django会自动转换,但更严谨的做法是使用datetime.date.today()来保证类型匹配。
2. 解决方案:两种优化方式
方式一:直接使用模型实例(推荐)
修改视图中的查询逻辑,去掉.values(),直接获取关联了用户的is_Present实例:
# 修正日期类型,确保是Date对象 today = datetime.date.today() # 简化过滤条件,保留select_related优化查询性能 p = Paginator( is_Present.objects.filter(date=today, is_present=True).select_related('user'), 5 )
然后修改模板,因为现在循环的是is_Present实例,需要通过它的user外键属性访问用户名:
{% for present_record in users %} <table class="table align-left table-dark table-striped table-hover table-bordered"> <tbody> <tr> <td style="width: 25%;">{{ present_record.user.username }}</td> </tr> </tbody> </table> {% endfor %}
(把循环变量名改成present_record是为了避免和User模型混淆,你也可以继续用user,只要明确它是is_Present实例即可)
方式二:直接查询在场的User对象
如果你的需求只是显示在场用户的信息,也可以直接查询User模型,通过反向关联过滤:
today = datetime.date.today() # 通过is_Present的反向关系过滤出今日在场的用户,用distinct避免重复记录 present_users = User.objects.filter( is_present__date=today, is_present__is_present=True ).distinct() p = Paginator(present_users, 5)
这种情况下,模板可以保持原来的写法,因为循环的就是User实例:
{% for user in users %} <table class="table align-left table-dark table-striped table-hover table-bordered"> <tbody> <tr> <td style="width: 25%;">{{ user.username }}</td> </tr> </tbody> </table> {% endfor %}
3. 额外优化建议
- 模型类名建议遵循PEP8规范,用大驼峰命名:比如
IsPresent代替is_Present,ClockedTime代替clocked_Time,这样代码更易读。 - 视图中的
elif request.user.is_superuser可以简化,因为前面已经判断了not request.user.is_superuser or not request.user.is_staff,剩下的必然是超级用户,不需要重复判断。
内容的提问来源于stack exchange,提问作者rhys
相关产品推荐
相关产品推荐

