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

如何在Django中用CBV实现关注/取消关注系统?请排查代码故障

关注系统故障排查与修复方案

问题概述

多次尝试实现关注系统,其中AddFollower和RemoveFollower类视图无法正常工作。尝试获取当前访问用户的Profile及自身Profile,对数据库执行添加/移除操作但无效果,附上相关代码寻求解决办法。

现有代码

urls.py

urlpatterns = [
    path('', PostListView.as_view(), name='blog-home'),
    path('user/<str:username>/', GetUserProfile.as_view(), name='user-profile'),
    path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
    path('post/new/', PostCreateView.as_view(), name='post-create'),
    path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
    path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
    path('about/', views.about, name='blog-about'),
    path('post-like/<int:id>/', views.post_like, name='post-like'),
    path('read-later/<int:id>/', views.read_later, name='read-later'),
    path('read-later-list/<str:username>/', ReadLaterListView.as_view(), name='read-later-list'),
    path('add-follower/<str:username>/', AddFollower.as_view(), name='add_follower'),
    path('remove-follower/<str:username>/', RemoveFollower.as_view(), name='remove_follower')
]

views.py

class AddFollower(LoginRequiredMixin, View):
    def post(self, request, *args, **kwargs):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        profile = Profile.objects.get(user=user)
        profile.subscribers.add(request.user)
        return redirect('user-profile', username=profile.user.username)

class RemoveFollower(LoginRequiredMixin, View):
    def post(self, request, *args, **kwargs):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        profile = Profile.objects.get(user=user)
        profile.subscribers.remove(request.user)
        return redirect('user-profile', username=profile.user.username)

user_posts.html

{% if is_following %}
   <form action="{% url 'remove_follower' user.username %}" method="POST">
    {% csrf_token %}
    <div class="buttons mt-3">
        <button type="submit" class="btn btn-dark px-4 ms-3">Unfollow</button>
    </div>
   </form>
{% else %}
   <form method="POST" action="{% url 'add_follower' user.username %}">
    {% csrf_token %}
    <div class="buttons mt-3">
        <button type="submit" class="btn btn-dark px-4 ms-3">Follow</button>
    </div>
   </form>
{% endif %}

故障排查与修复步骤

1. 检查Profile模型定义

首先确认Profile模型中subscribers字段的定义是否正确,需为关联User的多对多字段,示例如下:

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

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    # 定义多对多字段,related_name用于反向查询当前用户关注的列表
    subscribers = models.ManyToManyField(User, related_name='following', blank=True)
    # 其他自定义字段...

若字段定义错误,会直接导致添加/移除关注操作失效。

2. 修复视图逻辑

现有视图存在两个潜在问题:未处理用户关注自己的无效操作,未做重复添加/移除的判断。修改后的视图代码:

class AddFollower(LoginRequiredMixin, View):
    def post(self, request, *args, **kwargs):
        target_user = get_object_or_404(User, username=self.kwargs.get('username'))
        # 禁止关注自己
        if target_user == request.user:
            return redirect('user-profile', username=target_user.username)
        target_profile = Profile.objects.get(user=target_user)
        # 避免重复添加关注
        if not target_profile.subscribers.filter(id=request.user.id).exists():
            target_profile.subscribers.add(request.user)
        return redirect('user-profile', username=target_user.username)

class RemoveFollower(LoginRequiredMixin, View):
    def post(self, request, *args, **kwargs):
        target_user = get_object_or_404(User, username=self.kwargs.get('username'))
        target_profile = Profile.objects.get(user=target_user)
        # 确认存在关注关系再移除
        if target_profile.subscribers.filter(id=request.user.id).exists():
            target_profile.subscribers.remove(request.user)
        return redirect('user-profile', username=target_user.username)

3. 确保模板变量is_following正确传递

模板中的is_following变量需要在GetUserProfile视图中生成并传入,修改该视图的get_context_data方法:

class GetUserProfile(DetailView):
    model = User
    template_name = 'user_posts.html'
    context_object_name = 'user'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        target_user = self.get_object()
        target_profile = Profile.objects.get(user=target_user)
        # 判断当前登录用户是否已关注目标用户
        context['is_following'] = target_profile.subscribers.filter(id=self.request.user.id).exists() if self.request.user.is_authenticated else False
        return context

4. 测试验证

  • 登录后访问其他用户的个人页面,点击「Follow」按钮,检查数据库中Profile_subscribers表是否新增对应记录
  • 点击「Unfollow」按钮,检查记录是否被移除
  • 验证关注自己的操作是否被拦截

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:40:23