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

使用Djongo关联MongoDB时Django外键操作报错求助

Django + Djongo 外键录入数据时SQL参数解析错误排查方案

问题描述

在Django中定义了两个模型Test_DB和ForeignKey_Test,后者包含指向前者的外键字段。通过Django默认管理面板录入数据时,触发Djongo错误:

The above exception ( Keyword: FAILED SQL: SELECT %(0)s AS "a" FROM "testapp_test_db" WHERE "testapp_test_db"."id" = %(1)s LIMIT 1 Params: (1, 1) Version: 1.3.6 Sub SQL: None FAILED SQL: None Params: None Version: None) was the direct cause of the following exception: 

推测是Djongo解析SQL时参数匹配异常导致。

模型代码:

class Test_DB(models.Model):
    name = models.CharField(max_length=50)

class ForeignKey_Test(models.Model):
    name = models.CharField(max_length=50)
    test_id = models.ForeignKey(to='Test_DB', on_delete=models.CASCADE)

核心依赖版本:

  • Django==4.1.1
  • djongo==1.3.6
  • pymongo==3.12.3

原因分析与解决办法

1. 版本兼容性问题

Djongo 1.3.6发布时间早于Django 4.1.1,对Django 4.x版本的ORM查询语法支持不完善,导致外键查询时参数解析出错。

解决步骤:

  • 升级Djongo到兼容Django 4.1的版本,推荐djongo==1.3.8或更高版本,同时同步升级pymongo到4.0+版本:
pip install --upgrade djongo pymongo

2. 外键字段命名冲突

外键字段命名为test_id,与MongoDB原生的_id字段命名规则冲突,Djongo在转换查询时出现参数映射错误。

解决步骤:

  • 修改外键字段名,避免以_id结尾,比如改为test_db:
class ForeignKey_Test(models.Model):
    name = models.CharField(max_length=50)
    test_db = models.ForeignKey(to='Test_DB', on_delete=models.CASCADE)
  • 执行迁移更新数据库结构:
python manage.py makemigrations
python manage.py migrate

3. Djongo模板解析BUG

错误信息显示SQL模板使用了位置参数%(0)s和%(1)s,但实际传入的参数元组无法匹配,属于Djongo的内部解析BUG。

临时修复方案:

  • 为外键字段指定db_column属性,明确映射到MongoDB的字段名:
class ForeignKey_Test(models.Model):
    name = models.CharField(max_length=50)
    test_id = models.ForeignKey(
        to='Test_DB', 
        on_delete=models.CASCADE,
        db_column='test_db_ref'
    )
  • 重新执行迁移后,再次尝试在admin面板录入数据。

验证流程

  1. 应用上述任一方案后,重启Django服务
  2. 先在admin中创建一条Test_DB数据
  3. 再创建ForeignKey_Test数据,关联已创建的Test_DB条目,提交后确认是否报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:35:36