You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:49:03