如何在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
相关产品推荐
相关产品推荐

