Flask+SQLAlchemy实现书籍下载:补全函数、模型及模板修正
解决方案
1. 是否需要在models.py中新增第三张表?
不需要手动创建第三张表,直接用Django内置的ManyToManyField就能实现用户与已下载书籍的关联。如果后续需要记录下载时间、下载次数这类额外信息,再自定义中间表(继承models.Model)并通过through参数关联即可。
示例models.py代码:
from django.contrib.auth.models import User from django.db import models class Book(models.Model): title = models.CharField(max_length=200) # 书籍其他字段,比如作者、封面等 class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) downloaded_books = models.ManyToManyField(Book, related_name='downloaded_by')
2. 编写download_book函数(views.py)
基于函数视图实现,确保用户已登录,处理书籍添加逻辑,避免重复下载:
from django.shortcuts import get_object_or_404, redirect from django.contrib.auth.decorators import login_required from .models import Book, UserProfile @login_required def download_book(request, book_id): book = get_object_or_404(Book, id=book_id) # 获取或创建用户的Profile实例 user_profile, _ = UserProfile.objects.get_or_create(user=request.user) # 添加书籍到已下载列表,add方法会自动去重 user_profile.downloaded_books.add(book) # 重定向回用户页面 return redirect('user_page')
3. 修正user_page.html中的循环代码
确保模板正确遍历当前用户的已下载书籍,处理空列表场景:
<div class="downloaded-books-section"> <h3>已下载书籍</h3> {% if user.userprofile.downloaded_books.all %} <ul> {% for book in user.userprofile.downloaded_books.all %} <li>{{ book.title }}</li> {% endfor %} </ul> {% else %} <p>暂无已下载书籍</p> {% endif %} </div>
注意:如果是直接在User模型扩展的ManyToManyField,则把user.userprofile.downloaded_books.all替换为user.downloaded_books.all即可。
内容的提问来源于stack exchange,提问作者rupertpurple
相关产品推荐
相关产品推荐

