如何在Django中扩展用户模型实现图书收藏功能?
Django收藏夹功能问题解决
我是Django新手,正在搭建一个可查看图书及作者数据库、将任意图书添加至“收藏夹”的网站。尝试通过扩展UserModel添加关联收藏图书的字段,已在后台管理界面看到UserProfile的收藏内容,但无法将视图与bookfavs.html关联以让用户查看自己的收藏图书,页面仅显示用户名,不展示收藏内容。项目app名称为bookshelf,相关代码如下:
Models.py
class UserProfile(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) favorites = models.ManyToManyField(Book, related_name='favourites') class Author(models.Model): first_name=models.CharField(max_length=30) last_name=models.CharField(max_length=30) dob = models.DateField() bio = models.CharField(max_length=300) def __str__(self): return self.first_name + " " + self.last_name def get_absolute_url(self): return reverse('authorlist') class Book(models.Model): id = models.AutoField(primary_key=True) users = models.ManyToManyField(User) title = models.CharField(max_length=50) num_page = models.IntegerField() date_pub = models.DateField() tags = models.CharField(max_length=200) blurb = models.CharField(max_length=300) def get_absolute_url(self): return reverse('')
views.py
#Add favourite button...? def favorite(request, pk): if request.method == 'POST': favorite = Book.objects.get(pk=pk) user = request.user user.favorites.add(favorite) messages.add_message(request, messages.INFO, 'Book Favorited.') return redirect('home') #List ALL books class BookList(ListView): model = Book template_name='bookshelf/booklist.html' #List favourite books class BookFavs(TemplateView): model = UserProfile template_name = 'bookshelf/bookfavs.html' def get_context_data(self,*args, **kwargs): context = super(BookFavs, self).get_context_data(*args,**kwargs) context['users'] = UserProfile.objects.all() return context
bookfavs.html
{% if user.username %} <h4 class="header-greet">Welcome {{ user.username }} to your books!</h4> {% endif %} {% if user.is_authenticated %} {% with userprofile.favorites.all as favourite_books %} {% for book in book_list %} {% if book in favorite_book %} <p>{{ book.title }}</p> {% endif %} {% endfor %} {% endwith %} {% endif %}
问题修复步骤
1. 修正UserProfile与User的关联关系
一个用户对应唯一的UserProfile,把ForeignKey改成OneToOneField:
class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) # 修改此处 favorites = models.ManyToManyField(Book, related_name='favourites')
2. 修复添加收藏的视图函数
favorites字段属于UserProfile而非User本身,需先获取当前用户的UserProfile再添加收藏:
def favorite(request, pk): if request.method == 'POST': favorite_book = Book.objects.get(pk=pk) # 获取当前用户的UserProfile user_profile = UserProfile.objects.get(user=request.user) user_profile.favorites.add(favorite_book) messages.add_message(request, messages.INFO, '图书已收藏') return redirect('home')
3. 调整收藏列表视图,传递当前用户的收藏数据
不要传递所有UserProfile,仅获取当前登录用户的收藏图书:
class BookFavs(TemplateView): template_name = 'bookshelf/bookfavs.html' def get_context_data(self,*args, **kwargs): context = super().get_context_data(*args,**kwargs) # 获取当前用户的UserProfile及收藏图书 user_profile = UserProfile.objects.get(user=self.request.user) context['favorite_books'] = user_profile.favorites.all() return context
4. 修复模板渲染逻辑
模板中无userprofile和book_list变量,直接使用视图传递的favorite_books循环,同时修正变量名拼写错误:
{% if user.username %} <h4 class="header-greet">欢迎 {{ user.username }} 查看你的收藏!</h4> {% endif %} {% if user.is_authenticated %} {% if favorite_books %} {% for book in favorite_books %} <p>{{ book.title }}</p> {% endfor %} {% else %} <p>你还没有收藏任何图书哦~</p> {% endif %} {% endif %}
5. 补充用户创建时自动生成UserProfile的信号(可选但重要)
避免用户创建后无对应UserProfile导致报错,在models.py末尾添加:
from django.db.models.signals import post_save from django.contrib.auth.models import User from django.dispatch import receiver @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: UserProfile.objects.create(user=instance) @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): instance.userprofile.save()
6. 确保路由配置正确
在urls.py中配置收藏列表的路由:
from django.urls import path from . import views urlpatterns = [ # 其他路由... path('favorites/', views.BookFavs.as_view(), name='bookfavs'), path('favorite/<int:pk>/', views.favorite, name='favorite'), ]
内容的提问来源于stack exchange,提问作者Steve W
相关产品推荐
相关产品推荐

