Django for循环仅显示最后迭代:书籍推荐应用模板渲染问题
解决Django书籍推荐模板仅显示最后一条结果的问题
问题概述
开发Django书籍推荐应用时,机器学习模型已能从CSV文件获取推荐书籍ID,终端打印显示三次迭代的QuerySet均正常,但模板仅渲染最后一本推荐书籍的详情。核心原因是循环中每次覆盖了存储结果的变量,未将所有推荐书籍对象收集起来。
问题代码分析
原视图循环部分存在逻辑缺陷:
for i in recommend: new = Book.objects.filter(id=i) # 每次循环都会覆盖new变量,最终仅保留最后一次查询的QuerySet
最终传递给模板的new只是最后一本书的查询结果,因此模板循环只能显示单条数据。
解决方法
初始化一个列表来收集所有推荐书籍对象,避免循环中覆盖变量,具体修改如下:
修改后的views.py代码片段
def s_detail(request, book_id): #student paper detail cosine_sim = joblib.load('cosine_sim-v5.pkl') #load the ml model data = pd.read_csv('try.csv', sep=',', encoding='utf-8') try: book = Book.objects.get(pk=book_id) fav = True if book.favorites.filter(id=request.user.id).exists(): fav=False def recommendations(book_id,n, cosine_sim = cosine_sim): recommended_books = [] idx = book_id score_series = pd.Series(cosine_sim[idx]).sort_values(ascending = False) top_n_indexes = list(score_series.iloc[1:n+1].index) for i in top_n_indexes: recommended_books.append(list(data.index)[i]) # data.index for book_id column return recommended_books recommend = recommendations(book_id, 3) # 初始化列表存储所有推荐书籍对象 recommended_book_objects = [] for i in recommend: # 捕获书籍不存在的情况,避免CSV与数据库ID不匹配导致报错 try: book_obj = Book.objects.get(id=i) recommended_book_objects.append(book_obj) except Book.DoesNotExist: continue except Book.DoesNotExist: raise Http404("Title does not exist") # 将收集好的书籍列表传递给模板 return render (request, 'books/s_detail.html', {'book':book, 'fav':fav, 'recommend':recommend, 'new':recommended_book_objects})
模板代码无需修改
原模板的{% for book in new %}循环可直接遍历修改后的列表,正常渲染所有推荐书籍内容。
关键说明
- 新增
recommended_book_objects列表,专门存储每一本推荐的Book实例,彻底解决变量被覆盖的问题 - 添加
try-except逻辑,处理CSV中存在但数据库未收录的书籍ID,避免程序报错 - 最终传递给模板的
new是包含所有推荐书籍的列表,模板循环可完整渲染全部结果
内容的提问来源于stack exchange,提问作者anjgdpr
相关产品推荐
相关产品推荐

