Django模板渲染异常:所有课程显示全部上传文件求助
解决每个课程显示所有上传文件的问题
我来帮你搞定这个问题!核心问题出在模型关系设计和模板数据调用上,咱们一步步改:
1. 修正模型关系(关键!)
你原本用OneToOneField关联Lecture和FileUpload,这意味着每个课程只能绑定一个文件,完全不符合你「多个文件」的需求。咱们反过来,给FileUpload加一个指向Lecture的外键,这样一个课程就能对应多个文件了:
class Lecture(models.Model): course = models.ForeignKey('Course', on_delete=models.CASCADE, default='', related_name='lectures') lecture_category = models.IntegerField(choices=((0, "Classes "), (1, "Seminars"), ), default=0) lecture_title = models.CharField(max_length=100) content = models.TextField() def __str__(self): return self.lecture_title # 改成显示标题,后台管理更直观 class FileUpload(models.Model): # 新增外键,关联到对应的课程,related_name方便反向查询 lecture = models.ForeignKey(Lecture, on_delete=models.CASCADE, related_name='files') files = models.FileField(upload_to='documents', null=True, blank=True) def __str__(self): return str(self.files) def file_link(self): if self.files: return "<a href='%s'>download</a>" % (self.files.url,) else: return "No attachment" file_link.allow_tags = True file_link.short_description = 'File Download'
改完后记得执行数据库迁移命令:
python manage.py makemigrations python manage.py migrate
2. 简化视图函数
现在不需要把所有文件都传到模板里了,通过课程的反向关联就能拿到对应文件,所以视图可以简化:
def courses(request, slug): # 直接获取单个课程对象,比QuerySet更方便 course = Course.objects.get(slug=slug) # 按分类排序课程下的所有讲座 lectures = course.lectures.order_by('lecture_category') context = { 'course': course, 'lectures': lectures, } return render(request, 'courses/courses.html', context)
3. 修改模板,只显示当前课程的文件
模板里原来循环所有files的逻辑要改成循环当前讲座(c)关联的文件,利用我们设置的related_name='files'直接调用c.files.all():
<ul> {% regroup lectures by get_lecture_category_display as category_list %} <h3>Lectures</h3> <ul> {% for category in category_list %} <strong> <li>{{ category.grouper }}</li> </strong> <ul> {% for c in category.list %} <li>{{ c.lecture_title }}</li> <li>{{ c.content }}</li> <!-- 循环当前讲座的所有文件 --> {% for file in c.files.all %} {% if file.files %} <li><a href='{{ file.files.url }}'>download {{ file.files.name }}</a></li> {% else %} <li>No attachment</li> {% endif %} <!-- 如果没有文件,显示提示 --> {% empty %} <li>No files attached</li> {% endfor %} {% endfor %} </ul> {% endfor %} </ul> </ul>
为什么原来的代码会显示所有文件?
因为你在视图里传了files: FileUpload.objects.all(),模板里循环这个所有文件的集合,自然每个课程都会显示全部文件。现在通过模型的外键关联,每个讲座只能拿到自己绑定的文件,就解决问题啦!
内容的提问来源于stack exchange,提问作者user9092892
相关产品推荐
相关产品推荐

