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

Django生产环境使用PostgreSQL出现quiz.models.Question.DoesNotExist报错

问题根因

  1. 你的代码逻辑采用前端提交的问题文本作为唯一查询条件匹配Question表记录,该设计存在数据库兼容问题:
    • SQLite默认字符串匹配为大小写不敏感,且会自动忽略部分不可见字符差异,所以开发环境运行正常
    • PostgreSQL默认字符串匹配为大小写敏感,同时会严格校验所有字符包括空格、换行、富文本HTML标签格式,只要提交文本和数据库存储的text字段有任何细微差异就会查询失败
  2. 你用的RichTextUploadingField存储的是带HTML标签的富文本,前端渲染和提交时很容易出现标签格式、空格、换行的细微变化,本身就不适合作为查询条件使用
  3. 代码中if Question.objects.all():的判断完全不起容错作用,只要Question表存在任意数据就会进入查询逻辑,无法避免单个key匹配失败的报错

修复方案

长期最优方案(推荐)

1. 修改前端提交逻辑

不要用问题文本作为表单字段的key,改为用Question的主键id作为key,比如前端渲染问题时,每个问题的input/select的name属性设置为question_{{ question.id }},提交到后端的key为问题id而非文本。

2. 调整后端查询逻辑

将原有的文本查询替换为主键id查询,性能和稳定性都远高于文本匹配:

def save_quiz_view(request, pk, book_pk):
    quiz = Quiz.objects.get(pk=pk)
    if request.is_ajax() and not request.user.profile in quiz.completed_users.all():
        questions = []
        data = request.POST
        data_ = dict(data.lists())

        data_.pop('csrfmiddlewaretoken')

        for _k in data_.keys():
            # 提取key中的问题id,如key为question_12则提取数值12
            question_id = _k.split('_')[-1]
            question = Question.objects.get(id=question_id)
            questions.append(question)
        
        # 后续获取用户提交答案的逻辑也对应改为用id作为key取值
        # 其余原有逻辑保持不变即可

临时兼容方案

如果暂时无法修改前端代码,可以先将查询改为PostgreSQL支持的大小写不精确匹配,临时解决报错问题:

# 把原代码中的question = Question.objects.get(text=k)替换为
question = Question.objects.get(text__iexact=k)

注意:该方案仅为临时修复,富文本的不可见字符差异仍可能导致查询失败,长期仍建议改用主键id作为查询条件

补充校验

部署后先核对生产环境PostgreSQL的Question表数据是否和开发环境一致,确认数据迁移导入时没有出现富文本转义、格式丢失的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:45:02