Django实现按天(行)时段(列)匹配渲染课程表数据问题求解
课程表排布错位/课程不显示问题修复
问题根因
- 模板硬编码了时段判断条件
lesson.meet_time == '13:00 - 15:00',其余时段的课程全部被拦截不会渲染 - 渲染逻辑仅按天遍历后匹配当日课程,没有逐列遍历所有时段生成对应单元格,无课位置不会输出空
<td>,导致单元格和表头时段列错位 - 视图层没有提前结构化排课数据,模板层循环全量数据匹配效率低,逻辑容易出错
修复步骤
1. 调整视图函数,提前结构化排课数据
将排课数据处理为以「星期_时段」字符串为键、课程对象为值的字典,同时给星期、时段查询结果加上排序,避免展示顺序混乱,修改后代码如下:
def lecturerTimeTable(request): lecname = Lecturer.objects.get(user=request.user.id) # 获取当前讲师所有排课 raw_schedule = TeachingTimetable.objects.filter(lecturer=lecname).order_by('meet_time') # 结构化排课映射,方便模板直接按位置取值 schedule_map = {} for lesson in raw_schedule: map_key = f"{lesson.meet_day}_{lesson.meet_time}" schedule_map[map_key] = lesson # 去重后排序,保证星期、时段按固定顺序展示 days = MeetingTime.objects.all().values_list('day', flat=True).distinct().order_by('day') slots = MeetingTime.objects.all().values_list('time', flat=True).distinct().order_by('time') context = { 'schedule_map': schedule_map, 'program': Program.objects.all(), 'days': days, 'slots': slots, 'url_name':'class', 'lecturer':lecname, 'StarterPage':'Class-Timetable' } return render(request,'users/class_timetable.html',context)
2. 配置自定义模板过滤器
Django模板默认不支持用动态拼接的键取字典值,需要新增一个简单的自定义过滤器:
- 在对应app目录下新建
templatetags文件夹,文件夹内新建空文件__init__.py和文件custom_tags.py - 在
custom_tags.py中写入以下代码:
from django import template register = template.Library() @register.filter def get_item(dictionary, key): return dictionary.get(key)
3. 修改模板代码,按行列双层循环渲染
模板最顶部先加载自定义过滤器,之后渲染表格时,每行(对应星期)内层逐列(对应时段)遍历,从结构化映射中取对应位置的课程,无课程时渲染空单元格,保证列数和表头完全对齐:
{% load custom_tags %} <table class="table table-striped table-bordered table-hover"> <thead> <tr> <th colspan="8"><center>{{lecturer}}</center></th> </tr> <tr> <th></th> {% for time in slots %} <th class="time">{{time}}</th> {% endfor %} </tr> </thead> <tbody> {% for day in days %} <tr> <th>{{day}}</th> {% for slot in slots %} <td> {% with map_key=day|add:"_"|add:slot %} {% with current_lesson=schedule_map|get_item:map_key %} {% if current_lesson %} {{current_lesson.course}} <br> {{current_lesson.lecturer}}<br> {{current_lesson.venue}}<br> {{current_lesson.meet_day}} {{current_lesson.meet_time}} {% endif %} {% endwith %} {% endwith %} </td> {% endfor %} </tr> {% endfor %} </tbody> </table>
内容的提问来源于stack exchange,提问作者Andrea Mpulila
相关产品推荐
相关产品推荐

