Django视图调用同一模型两字段及模板显示为空问题解决
问题分析与解决方案
核心问题
- 视图中book变量的冗余与错误覆盖:先通过
get_object_or_404获取单个书籍对象,随后又用filter将其覆盖为QuerySet,不仅冗余,还可能导致模板渲染异常;同时try-except块完全无效,因为filter不会抛出异常。 - 相似书籍查询逻辑错误:用
book_slug(书籍的slug)去匹配book_auther(作者字段),完全不符合需求,应该用当前书籍的作者来筛选相似书籍,还要排除当前书籍本身。 - 模板渲染逻辑错误:对单个书籍对象使用
for循环,无法渲染内容(因为单个对象不是可迭代的QuerySet)。
修正后的代码
视图代码
def book_details(request, book_slug): # 获取当前书籍单个对象,自动处理404 book = get_object_or_404(Book, book_slug=book_slug) # 筛选同作者的相似书籍,排除当前书籍本身 similar_books = Book.objects.filter(book_auther=book.book_auther).exclude(id=book.id) context = { 'book': book, 'similar_books': similar_books, } return render(request, 'book.html', context)
模板代码
<!-- 单本书籍详情展示,无需for循环 --> <div class="row"> <div> {% if book.book_picture %} <img src="{{ book.book_picture.url }}" class="Rounded circle Image" height="150" width="150" alt="{{ book.book_title }}"> {% endif %} <a href="{{ book.get_absolute_url }}">{{ book.book_title }}</a> <!-- 可按需添加其他字段展示 --> <p>作者:{{ book.book_auther }}</p> <p>{{ book.book_description|safe }}</p> </div> </div> <!-- 相似书籍列表,遍历QuerySet --> <div class="row"> {% for sb in similar_books %} <div> {% if sb.book_picture %} <img src="{{ sb.book_picture.url }}" class="Rounded circle Image" height="150" width="150" alt="{{ sb.book_title }}"> {% endif %} <a href="{{ sb.get_absolute_url }}">{{ sb.book_title }}</a> </div> {% empty %} <p>暂无同作者的相似书籍</p> {% endfor %} </div>
额外优化建议
- 模型中
book_auther字段拼写错误,建议修正为book_author,避免后续维护混淆。 - 为
book_slug添加唯一性约束:book_slug = models.SlugField(blank=True, allow_unicode=True, editable=True, unique=True),确保每个书籍slug唯一。 - 模板中增加图片存在性判断,避免因图片为空触发
AttributeError。
内容的提问来源于stack exchange,提问作者Tarek Hussien
相关产品推荐
相关产品推荐

