如何在Django+Djongo+MongoDB中建立一对一模型关系?
解决Django+Djongo中OneToOneField递归溢出的DatabaseError
问题根源
你给PresentEmployee的OneToOneField命名为employee_id,刚好和关联的Employee模型的主键字段名完全重复。Djongo在处理MongoDB的关联映射时,会因为这个字段名冲突触发循环查询逻辑,最终导致递归深度超出的DatabaseError。另外你的__str__方法直接返回str(self.employee_id),访问这个关联字段时会触发额外的数据库查询,进一步加剧了递归问题。
修复方案
1. 修改关联字段名
把PresentEmployee里的OneToOneField字段名改成和Employee主键不重复的名字,比如employee,避免Djongo解析时混淆。
2. 调整__str__方法
直接引用关联对象的具体属性(比如employee_name),不要直接转整个关联对象,减少不必要的查询调用。
修改后的模型代码
Employee模型(保持不变)
class Employee(models.Model): employee_id = models.CharField(primary_key=True, max_length=10, null=False, blank=False) employee_name = models.CharField(max_length=200, null=False, blank=False) email = models.EmailField(max_length=500, null=True, blank=True) def __str__(self): return self.employee_name
PresentEmployee模型(已修复)
import uuid from django.db import models class PresentEmployee(models.Model): # 字段名改为employee,避免和Employee的主键重名 employee = models.OneToOneField(Employee, on_delete=models.CASCADE) present_id = models.IntegerField(null=False, blank=False) id = models.UUIDField(default=uuid.uuid4, primary_key=True, editable=False) def __str__(self): # 直接返回关联员工的姓名,避免递归调用 return self.employee.employee_name
测试验证
按以下代码创建对象,不会再触发递归错误:
# 创建员工对象 emp = Employee.objects.create(employee_id="E001", employee_name="张三", email="zhangsan@example.com") # 创建在职员工对象 present_emp = PresentEmployee.objects.create(employee=emp, present_id=1001) print(present_emp) # 正常输出"张三"
额外说明
Djongo作为Django和MongoDB的适配层,对关联字段的处理逻辑和PostgreSQL这类关系型数据库不一样。关系型数据库允许外键字段名和关联表主键同名,但MongoDB是文档型数据库,Djongo靠字段名来识别关联关系,重名会导致解析逻辑混乱,所以一定要避免关联字段名和关联模型的主键字段重复。
内容的提问来源于stack exchange,提问作者Ajdal
相关产品推荐
相关产品推荐

