一、收藏功能的数据模型设计
收藏功能的核心是:一个用户可以收藏多篇文章,一篇文章可以被多个用户收藏。这是典型的多对多(ManyToMany)关系。
我们不需要新建模型——Django 的 User 模型是内置的,只需要在 Post 模型中添加一个 ManyToManyField 指向 User。
python
# 文件路径:blog/models.py 的 Post 类中添加 from django.contrib.auth.models import User class Post(models.Model): # ... 已有字段 ... # 收藏者:ManyToManyField 自动创建中间表 favorites = models.ManyToManyField( User, related_name='favorite_posts', # 反向查询:user.favorite_posts.all() verbose_name='收藏者', blank=True )
参数说明:
| 参数 | 作用 |
|---|---|
User | 关联的目标模型 |
related_name='favorite_posts' | 反向查询名称,user.favorite_posts.all() |
verbose_name='收藏者' | Admin 后台显示的中文名 |
blank=True | 表单中允许为空 |
中间表说明:
ManyToManyField 会自动创建一张中间表(如 blog_post_favorites),包含 post_id 和 user_id 两个外键字段,无需手动定义。
修改模型后,生成并执行迁移:
bash
(venv) $ python manage.py makemigrations (venv) $ python manage.py migrate
二、收藏与取消收藏的视图逻辑
python
# 文件路径:blog/views.py 新增 from django.shortcuts import render, redirect, get_object_or_404 from django.contrib.auth.decorators import login_required from django.contrib import messages from .models import Post # login_required 装饰器:未登录用户访问此视图时,自动跳转到登录页 @login_required def toggle_favorite(request, pk): """切换收藏状态:收藏 → 取消,未收藏 → 收藏""" post = get_object_or_404(Post, pk=pk) # 检查当前用户是否已收藏 if post.favorites.filter(id=request.user.id).exists(): # 已收藏 → 取消收藏 post.favorites.remove(request.user) messages.info(request, f'已取消收藏「{post.title}」') else: # 未收藏 → 添加收藏 post.favorites.add(request.user) messages.success(request, f'已收藏「{post.title}」') # 重定向回当前页面(HTTP_REFERER 是来源页面的 URL) referer = request.META.get('HTTP_REFERER', '/') return redirect(referer)
关键点解析:
| 代码 | 说明 |
|---|---|
@login_required | 未登录用户自动跳转到登录页 |