Django集成MongoDB后Admin后台创建Order时出现“Select a valid choice. That choice is not one of the available choices.”错误求助
解决Django + Djongo Admin中ForeignKey选择无效的问题
看起来你遇到的问题是因为自定义ObjectId主键没有正确设置,导致Django的ForeignKey关联和Admin验证出现了不匹配。让我一步步帮你排查和解决:
问题根源分析
你在Profile模型中定义了_id = ObjectIdField(),但没有将它设置为primary_key=True。这会导致Django自动生成一个默认的id字段(整数类型)作为模型的主键,而Order模型中的profile外键默认关联的是这个自动生成的id,不是你自定义的_id。
但在Admin界面中,当你选择Profile选项时,表单提交的是你自定义的_id值,而系统验证时期望的是默认主键id的值,因此会提示“Select a valid choice. That choice is not one of the available choices.”。
解决方案步骤
1. 修改模型,将自定义_id设为主键
更新app/models.py中的Profile和Order模型,给_id字段加上primary_key=True:
from django.db import models from djongo.models.fields import ObjectIdField from django.contrib.auth.models import User class Profile(models.Model): _id = ObjectIdField(primary_key=True) # 新增primary_key=True user = models.ForeignKey(User, on_delete=models.CASCADE) # 建议添加__str__方法,让Admin显示更友好 def __str__(self): return f"Profile for {self.user.username}" class Order(models.Model): _id = ObjectIdField(primary_key=True) # 新增primary_key=True profile = models.ForeignKey(Profile, on_delete=models.CASCADE) datetime = models.DateTimeField(auto_now_add=True) price = models.FloatField() quantity = models.FloatField()
2. 重置迁移与数据库数据
因为修改了主键字段,需要清理旧的迁移和MongoDB中的旧数据:
- 删除
app/migrations目录下除了__init__.py之外的所有文件 - 登录MongoDB,删除
engine数据库中的app_profile和app_order集合(如果有其他相关集合也一起删除) - 重新生成迁移并执行:
python manage.py makemigrations python manage.py migrate
3. 重新创建超级用户与测试
- 执行
python manage.py createsuperuser重新创建超级用户 - 启动服务器,进入Admin后台:
- 先创建关联超级用户的Profile
- 再创建Order,此时选择Profile选项后保存应该就能正常通过验证了
额外建议
- 确保你的
djongo版本是最新的,旧版本可能存在ForeignKey处理的bug:
pip install --upgrade djongo
- 如果你需要使用非主键字段作为外键关联,可以在
ForeignKey中指定to_field参数,但这种情况不推荐,尽量用主键关联更稳定。
内容的提问来源于stack exchange,提问作者zandrones
相关产品推荐
相关产品推荐

