Django模板报错:无法解析'topic_files.items()'中的'()',求解决
解决Django模板按主题分组显示文件的语法错误及优化方案
错误原因
你遇到的TemplateSyntaxError是因为Django模板语法不允许在遍历字典时使用带括号的items()方法——模板会自动识别字典的可迭代性,直接用.items即可,不需要加括号调用。
快速修复模板
1. 修正字典遍历语句
把模板里的:
{% for topic, files in topic_files.items() %}
改成:
{% for topic, files in topic_files.items %}
2. 简化空文件判断
模板里的{% if not topic_files[topic] %}可以直接用循环内的files变量替代,更简洁且避免模板字典索引的潜在问题:
{% if not files %} <div class="alert alert-warning" role="alert"> No files uploaded for this topic yet. </div> {% endif %}
优化视图查询(减少数据库请求)
你当前的视图中,topic_files是通过循环每个topic单独查询文件,会产生N+1次数据库请求(N是topic数量)。可以用prefetch_related优化查询,一次性获取所有关联数据:
修改后的视图代码:
from django.db.models import Prefetch def admin_submission_details(request, sub_id): if request.user.is_authenticated: submission = get_object_or_404(Submission, pk=sub_id) # 预取当前提交下对应主题的文件 topics = Topic.objects.filter(research_work=submission.research_work).prefetch_related( Prefetch( 'files', queryset=File.objects.filter(submission=submission), to_attr='submission_files' # 给预取的文件命名,避免和原files关联混淆 ) ) context = {'submission': submission, 'topics': topics} return render(request, 'users/admin_submission_details.html', context=context) else: messages.error(request, 'Invalid user') return redirect('login')
对应的模板代码也可以调整,直接用每个topic的submission_files属性:
{% block content %} <div class="body flex-grow-1 px-3"> <div class="container-lg"> {% for topic in topics %} <div class="card mb-4"> <div class="card-header"> <strong>{{topic.name}}</strong> </div> <div class="card-body"> <div class="example"> <div class="table table-responsive"> <table class="table align-middle"> <thead> <tr> <td style="width: 20%" scope="col">Файл</td> <td style="width: 20%" scope="col">Дата</td> <td style="width: 20%" scope="col">Статус проверки</td> <td style="width: 20%" scope="col">Комментарий</td> </tr> </thead> <tbody> {% for file in topic.submission_files %} <tr> <td> <a href="{{file.filename.url}}" target="_blank">{{ file.filename}}</a> </td> <td>{{ file.upload_date|date:"Y-m-d H:i"}}</td> {% if file.is_reviewed %} {% if file.is_accepted %} <td style="color: green">Принято</td> {% else %} <td style="color: red">Не принято</td> {% endif %} {% else %} <td style="color: orange">На проверке</td> {% endif %} <td>{{file.comment}}</td> </tr> {% endfor %} </tbody> </table> </div> {% if not topic.submission_files %} <div class="alert alert-warning" role="alert"> No files uploaded for this topic yet. </div> {% endif %} </div> </div> </div> {% endfor %} </div> </div> <script> document.addEventListener("DOMContentLoaded", function () { const clickableRows = document.querySelectorAll(".clickable-row"); clickableRows.forEach((row) => { row.addEventListener("click", function () { window.location.href = this.getAttribute("data-href"); }); }); }); </script> {% endblock content %}
说明
- 优化后的视图通过
Prefetch精准获取当前提交下的主题文件,只需要2次数据库查询(一次查topics,一次查对应files),性能更优。 - 模板中直接使用topic的
submission_files属性,逻辑更清晰,也避免了字典遍历的语法问题。
内容的提问来源于stack exchange,提问作者Nika
相关产品推荐
相关产品推荐

