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

使用Djongo向MongoDB写入嵌套数据失败,求解决方案

Django + Djongo 嵌套数据存储问题解决

问题场景

在Django中使用Djongo操作MongoDB时,尝试通过ArrayField嵌套Employee模型实现文档内嵌入数组结构,执行迁移后发现Company集合中并未存储employees字段及对应嵌套数据。

现有模型代码

from django.db import models
from djongo.models import ArrayField, ObjectIdField

class Employee(models.Model):
    id = models.ObjectIdField()
    name = models.CharField(max_length=255)
    age = models.IntegerField()
    email = models.EmailField()
    phone_number = models.CharField(max_length=20)
    
    def __str__(self) -> str:
        return self.name

class Company(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    location = models.CharField(max_length=255)
    email = models.EmailField()
    employees = models.ArrayField(
        model_container=Employee,
        null=True,
        blank=True,
    )
    
    def __str__(self):
        return self.name

当前MongoDB存储结果

{
  "_id": {
    "$oid": "66c8b0c7fc77e7422da0e80d"
  },
  "id": 2,
  "name": "dgdhg",
  "description": "abhdj",
  "location": "sdsgh",
  "email": "xeno@gmail.com"
}

期望的文档结构

{
    "name": "John",
    "location": "Sargodha",
    "description": "kjjlyyf",
    "email": "hvh@gmail.com",
    "employees": [
        {
            "id": 1,
            "name": "hassan",
            "age": 23,
            "email": "adeebhassi@gmail.com",
            "phone_number": "2394820948"
        }
    ]
}

解决方案

1. 调整模型继承关系

嵌入式文档不能继承models.Model(否则会被识别为独立集合),需改用Djongo提供的EmbeddedModel:

from django.db import models
from djongo.models import ArrayField, ObjectIdField, EmbeddedModel

class Employee(EmbeddedModel):  # 改为继承EmbeddedModel
    id = models.ObjectIdField()
    name = models.CharField(max_length=255)
    age = models.IntegerField()
    email = models.EmailField()
    phone_number = models.CharField(max_length=20)
    
    def __str__(self) -> str:
        return self.name

class Company(models.Model):
    name = models.CharField(max_length=255)
    description = models.TextField()
    location = models.CharField(max_length=255)
    email = models.EmailField()
    employees = models.ArrayField(
        model_container=Employee,
        null=True,
        blank=True,
    )
    
    def __str__(self):
        return self.name

2. 正确保存嵌套数据

创建并保存数据时,需直接实例化Employee并添加到employees数组中:

# 示例代码
from your_app.models import Company, Employee

# 创建嵌入式员工对象
emp = Employee(
    name='hassan',
    age=23,
    email='adeebhassi@gmail.com',
    phone_number='2394820948'
)

# 创建公司并关联员工数组
comp = Company(
    name='John',
    location='Sargodha',
    description='kjjlyyf',
    email='hvh@gmail.com',
    employees=[emp]
)
comp.save()

3. 重新执行迁移

删除应用下migrations目录中除__init__.py外的所有文件,然后重新生成并应用迁移:

python manage.py makemigrations
python manage.py migrate

原因说明

原代码中Employee继承models.Model,Djongo会将其视为独立的MongoDB集合,而非Company文档内的嵌入式结构,因此ArrayField无法正确嵌入员工数据。改用EmbeddedModel后,Djongo会将Employee解析为嵌套文档,从而实现预期的数组嵌入存储。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:42:35