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

Django部署Heroku后评论表单用户下拉列表为空问题咨询

问题根因

核心问题是代码里存在两套完全独立、无关联的User模型,和Heroku部署环节本身无关:

  • 你在main/models.py里自定义了User模型,对应后台「Main」板块下的用户数据;Django自带的django.contrib.auth.models.User是认证系统用的用户模型,对应后台「AUTHENTICATION AND AUTHORIZATION」板块下的用户数据,二者是完全分开的两张数据库表,没有任何自动同步逻辑。
  • 现有注册逻辑调用的是Django内置认证系统的用户创建接口,新用户只会写入认证系统的User表,不会自动在你自定义的main.User表生成记录。
  • 评论表单的用户下拉列表取的是main.User表的全部数据,这张表本身没有对应注册用户的记录,自然显示为空。
  • 本地之前表现"正常"只是因为你曾经手动在main.User表里添加过测试数据,新注册用户不同步到Main板块的问题本地一直存在,只是之前未排查到。

修复方案

推荐使用第一种方案,是Django官方认可的自定义用户模型的标准实现,长期维护不会出现数据不一致问题。

方案1:统一用户模型(推荐)

  1. 修改main/models.py中的自定义User模型,继承Django内置的AbstractUser,替换原有独立的User模型定义:
    from django.db import models
    from django.contrib.auth.models import AbstractUser
    from decimal import Decimal
    import locale
    import logging
    
    
    class User(AbstractUser):
        # AbstractUser已经自带username、password、email、first_name、last_name等认证所需的默认字段
        # 如果你需要保留自定义的邮箱字段,可以取消下一行的注释,不需要就直接删除
        # email_address = models.EmailField('User Email Address')
        
        def __str__(self):
            return self.first_name + ' ' + self.last_name
    
  2. 打开项目全局的settings.py,添加配置指定自定义User模型为项目默认认证模型:
    AUTH_USER_MODEL = 'main.User'
    
  3. 清理旧的迁移和脏数据(因为之前已经生成过错误的用户模型迁移,必须做这步否则会报字段冲突):
    • 本地操作:删除main app下migrations文件夹里除__init__.py之外的所有文件,删除本地的db.sqlite3数据库文件
    • Heroku操作:如果Heroku端没有需要保留的生产数据,执行heroku run python manage.py flush清空数据库,或者直接重建Heroku Postgres实例
  4. 重新生成并执行迁移:
    本地终端执行:
    python manage.py makemigrations
    python manage.py migrate
    
    代码推送到Heroku后,在Heroku端执行迁移:
    heroku run python manage.py migrate
    
  5. 重新创建超级管理员账号:
    # 本地
    python manage.py createsuperuser
    # Heroku端
    heroku run python manage.py createsuperuser
    
  6. 修正评论提交视图的逻辑漏洞:当前视图没有绑定评论和提交用户的关系,用户可以通过下拉列表冒用其他人身份提交评论,直接取当前登录用户即可,修改add_review视图:
    @login_required
    def add_review(request, product_id):
        product = get_object_or_404(Product, pk=product_id)
        form = ReviewAdd(request.POST or None) 
        if form.is_valid():
            new_rating = form.save(commit=False)
            new_rating.product = product
            new_rating.user = request.user # 绑定当前登录用户,不需要用户手动选择
            new_rating.save()
            return redirect('home')
        return render(request, 'main/add_review.html',{'form':form})
    
    对应可以把ReviewAdd表单里的用户选择字段删除,避免越权问题。
  7. 部署检查:确认推送到Heroku的代码包含所有最新生成的迁移文件,每次部署后必须在Heroku端执行migrate命令同步表结构。

方案2:保留双模型,注册时同步数据(不推荐)

如果暂时不想重构用户模型,可以修改注册逻辑,在用户完成认证注册后,同步在main.User表创建对应记录:

def register(response):
    if response.method == "POST":
        form = RegisterForm(response.POST)
        if form.is_valid():
            new_user = form.save()
            # 同步创建Main板块下的用户记录
            from .models import User as MainUser
            MainUser.objects.create(
                first_name=new_user.first_name,
                last_name=new_user.last_name,
                email_address=new_user.email
            )
            new_user = authenticate(username=form.cleaned_data['username'],
                                    password=form.cleaned_data['password1'],)
            login(response, new_user)
            return HttpResponseRedirect("/home")
    else:
        form = RegisterForm()
    
    return render(response,"register/register.html", {"form":form})

注意这个方案需要手动给所有已经注册的老用户补建main.User表的对应记录,否则老用户依然不会出现在评论下拉列表里,后续用户修改个人信息时也需要做双表同步,维护成本很高。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 06:51:38