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

Django用户关注系统报错:no such column: blog_follow.followed_by_id

Django关注/取消关注系统错误修复方案

问题概述

开发Django用户关注系统时,访问页面触发错误:django.db.utils.OperationalError: no such column: blog_follow.followed_by_id,删除迁移文件重新执行makemigrations和migrate后问题仍存在。

核心错误原因

  1. 模型设计逻辑错误:User模型的followers字段错误关联了Follow模型,而非直接建立用户间的多对多关系,导致数据库表结构与代码逻辑不匹配。
  2. 迁移未正确同步:之前的错误模型生成的迁移文件未彻底清理,数据库表结构未更新到正确状态。
  3. 视图与模板的逻辑错误:视图中查询条件错误,模板中存在变量引用错误(如i.user.id应为i.id)。

分步修复方案

1. 修正模型结构

修改models.py,正确建立用户间的关注关系,利用Django的ManyToManyField结合自定义中间表:

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

class User(AbstractUser):
    # following表示当前用户关注的人,followers表示关注当前用户的人
    following = models.ManyToManyField(
        "self",
        through='Follow',
        symmetrical=False,
        related_name='followers'
    )

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.CharField(max_length=500, null=True, blank=True)
    timestamp = models.DateField(auto_now_add=True)
    like = models.ManyToManyField(User, blank=True, related_name="liked_posts")
    
    @property
    def number_of_likes(self):
        return self.like.all().count()
    
    def __str__(self) -> str:
        return self.post[:20]  # 显示前20个字符避免过长

class Follow(models.Model):
    followed_me = models.ForeignKey(User, on_delete=models.CASCADE, related_name='follow_records')
    followed_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='following_records')
    created_at = models.DateTimeField(auto_now_add=True)  # 记录关注时间

    class Meta:
        unique_together = ('followed_me', 'followed_by')  # 禁止重复关注同一用户

    def __str__(self) -> str:
        return f"{self.followed_by.username} 关注了 {self.followed_me.username}"

2. 重置迁移与数据库

注意:此操作会清空数据库数据,建议先备份数据!

  • 删除app目录下migrations文件夹中除__init__.py外的所有文件
  • 删除项目根目录的db.sqlite3文件(如果使用其他数据库,需手动清空对应表)
  • 重新生成迁移文件:
    python manage.py makemigrations
    
  • 同步数据库:
    python manage.py migrate
    

3. 修正视图逻辑

修改views.py中的查询与操作逻辑:

from django.shortcuts import render, get_object_or_404, redirect
from .models import User, Post, Follow

def profile(request, username):
    my_account = get_object_or_404(User, username=username)
    my_post = Post.objects.filter(user=my_account).order_by("-timestamp")  # 最新帖子在前
    following = False
    
    if request.user.is_authenticated:
        # 检查当前用户是否关注了目标用户
        following = my_account.followers.filter(id=request.user.id).exists()
    
    # 统计粉丝数与关注数
    follower_count = my_account.followers.count()
    following_count = my_account.following.count()

    return render(request, "blog/profile.html", {
        "posts": my_post,
        "post_count": my_post.count(),
        "following": following,
        "follower_count": follower_count,
        "following_count": following_count,
        "my_account": my_account
    })

def follow_list(request):
    all_users = User.objects.all()
    return render(request, "blog/following.html", {
        "al_us": all_users
    })

def follow_or_unfollow_user(request, user_id):
    if not request.user.is_authenticated:
        return redirect('login')  # 未登录用户跳转登录页面
    
    followed_user = get_object_or_404(User, id=user_id)
    if followed_user == request.user:
        return redirect('profile', username=request.user.username)  # 禁止关注自己
    
    # 切换关注状态
    follow_record, created = Follow.objects.get_or_create(
        followed_me=followed_user,
        followed_by=request.user
    )
    if not created:
        follow_record.delete()
    
    return redirect('profile', username=followed_user.username)

4. 修正模板错误

profile.html

<div>
    总帖子数 {{ post_count }} 
    <span>总粉丝数 {{ follower_count }}</span> 
    <span>关注数 {{ following_count }}</span>
    {% if user.is_authenticated and user != my_account %}
        {% if following %}
            <a href="{% url 'follow_or_unfollow' my_account.id %}">取消关注</a>
        {% else %}
            <a href="{% url 'follow_or_unfollow' my_account.id %}">关注</a>
        {% endif %}
    {% endif %}
</div> 

{% for pst in posts %}
<div class="post-outer-container">
    <div class="post-container">
        {{ pst.post }}
        <p>作者:{{ pst.user.username }} | 发布时间:{{ pst.timestamp }}</p>
        
        {% if user.id == pst.user.id %}
            <a href="{% url 'edit-post' pst.id %}" style="margin-left:15px ;">编辑</a>
            <a href="{% url 'delete' pst.id %}" style="margin-left:15px ;">删除</a>
        {% endif %}
    </div>
</div>
{% endfor %}

following.html

<h1>所有用户</h1>

{% for user_obj in al_us %}
    {% if user.id != user_obj.id %}
        <div>{{ user_obj.username }}</div>
        {% if user_obj in user.following.all %}
            <a href="{% url 'follow_or_unfollow' user_obj.id %}">取消关注</a>
        {% else %}
            <a href="{% url 'follow_or_unfollow' user_obj.id %}">关注</a>
        {% endif %}
    {% endif %}
{% endfor %}

5. 修正URL配置

确保urls.py中的路径正确:

from django.urls import path
from . import views

urlpatterns = [
    path("profile/<str:username>", views.profile, name="profile"),
    path("follow/list", views.follow_list, name="follow_list"),
    path("follow_or_unfollow/<int:user_id>", views.follow_or_unfollow_user, name="follow_or_unfollow"),
    # 其他URL...
]

验证修复

  1. 创建测试用户
  2. 访问用户主页,尝试关注/取消关注操作
  3. 检查粉丝数、关注数是否正确更新
  4. 确认页面不再出现no such column错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 19:01:28