You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django用户订阅关系实现求助:基于默认User模型构建博主订阅功能

嘿,我来帮你搞定这个Django博客的用户订阅功能!核心需求是实现用户之间的订阅关系——普通用户能关注文章作者,一个用户可以follow多个作者,一个作者也能被多个用户关注。结合你现有的Post模型和默认User模型,这里有两种实用的实现方案,你可以根据需求选择:

实现Django博客用户订阅功能

方案一:创建独立的Subscription模型(推荐,扩展性强)

这种方式的优势是可以轻松添加订阅时间、是否开启通知等额外字段,后续功能扩展会更灵活。

1. 定义Subscription模型

在你的app的models.py中添加以下代码:

from django.db import models
from django.contrib.auth.models import User

class Subscription(models.Model):
    # 订阅者(主动关注他人的用户)
    follower = models.ForeignKey(User, on_delete=models.CASCADE, related_name="following")
    # 被订阅者(被关注的作者)
    followed = models.ForeignKey(User, on_delete=models.CASCADE, related_name="followers")
    # 自动记录订阅时间
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        # 强制一个用户不能重复订阅同一个作者
        unique_together = ('follower', 'followed')
        verbose_name = "订阅"
        verbose_name_plural = "订阅列表"

    def __str__(self):
        return f"{self.follower.username} 订阅了 {self.followed.username}"

2. 执行数据库迁移

运行以下命令更新数据库结构:

python manage.py makemigrations
python manage.py migrate

3. 实现订阅/取消订阅的视图

在views.py中添加视图函数(这里用函数视图举例,类视图逻辑类似):

from django.shortcuts import get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from .models import Subscription

@login_required
def toggle_subscription(request, user_id):
    # 获取目标作者
    author = get_object_or_404(User, id=user_id)
    # 防止用户订阅自己
    if request.user == author:
        return redirect('post_list')  # 替换成你的文章列表页URL名称
    
    # 检查是否已订阅,存在则取消,不存在则创建
    subscription, created = Subscription.objects.get_or_create(
        follower=request.user,
        followed=author
    )
    
    if not created:
        subscription.delete()
    
    # 跳转回作者的文章页或之前的页面
    return redirect('author_posts', author_id=author.id)  # 替换成你的作者文章页URL名称

4. 添加URL路由

在urls.py中添加路由规则:

from django.urls import path
from . import views

urlpatterns = [
    # 其他现有路由...
    path('subscribe/<int:user_id>/', views.toggle_subscription, name='toggle_subscription'),
]

5. 在模板中添加订阅按钮

在作者的文章页或用户信息页,插入订阅/取消订阅的按钮:

{% if user.is_authenticated and user != author %}
    {% if user in author.followers.all %}
        <a href="{% url 'toggle_subscription' author.id %}" class="btn btn-danger">取消订阅</a>
    {% else %}
        <a href="{% url 'toggle_subscription' author.id %}" class="btn btn-primary">订阅</a>
    {% endif %}
{% endif %}

方案二:直接用User的ManyToMany关联(轻量版)

如果不需要额外字段,只是单纯实现订阅关系,可以通过User模型的ManyToMany字段简化实现。由于默认User模型无法直接修改,我们用OneToOne关联的Profile模型来扩展:

1. 定义UserProfile模型

from django.db import models
from django.contrib.auth.models import User

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    # 存储用户关注的作者列表
    following = models.ManyToManyField(User, related_name='followed_by', blank=True)

    def __str__(self):
        return self.user.username

添加信号自动为新用户创建Profile(放在models.py末尾):

from django.db.models.signals import post_save
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.profile.save()

执行数据库迁移后,这个模型就生效了。

2. 简化版订阅/取消视图

@login_required
def toggle_subscription(request, user_id):
    author = get_object_or_404(User, id=user_id)
    if request.user == author:
        return redirect('post_list')
    
    # 切换订阅状态
    if author in request.user.profile.following.all():
        request.user.profile.following.remove(author)
    else:
        request.user.profile.following.add(author)
    
    return redirect('author_posts', author_id=author.id)

模板中的按钮逻辑只需修改判断条件:

{% if user.is_authenticated and user != author %}
    {% if author in user.profile.following.all %}
        <a href="{% url 'toggle_subscription' author.id %}" class="btn btn-danger">取消订阅</a>
    {% else %}
        <a href="{% url 'toggle_subscription' author.id %}" class="btn btn-primary">订阅</a>
    {% endif %}
{% endif %}

额外功能:展示订阅列表与粉丝列表

在用户个人页面可以添加以下代码,展示用户的关注列表和粉丝列表:

<h3>我关注的作者</h3>
<ul>
    {% for user in request.user.following.all %} {# 方案一用这个 #}
    {% comment %} {% for user in request.user.profile.following.all %} {# 方案二用这个 #} {% endcomment %}
        <li><a href="{% url 'author_posts' user.id %}">{{ user.username }}</a></li>
    {% empty %}
        <li>还没有关注任何作者</li>
    {% endfor %}
</ul>

<h3>我的粉丝</h3>
<ul>
    {% for user in request.user.followers.all %} {# 方案一用这个 #}
    {% comment %} {% for user in request.user.followed_by.all %} {# 方案二用这个 #} {% endcomment %}
        <li>{{ user.username }}</li>
    {% empty %}
        <li>还没有粉丝</li>
    {% endfor %}
</ul>

内容的提问来源于stack exchange,提问作者Sasha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 07:38:06