django - Djongo数据库引擎上的Django Admin外键错误
问题描述
我正在将djongo包用于数据库后端引擎,以便连接到 MongoDB 并在其上定义我的模型。
设置.py:
DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': str(BASE_DIR / 'db.sqlite3'),
# },
'default': {
'ENGINE': 'djongo',
'NAME': 'djongo-db',
'ENFORCE_SCHEMA': False,
'CLIENT': {
'host': 'localhost',
'port': 27017,
'username': 'root',
'password': 'root',
'authSource': 'admin',
'authMechanism': 'SCRAM-SHA-1'
}
}
}
模型.py:
class EventModel(BaseModel)
name = models.CharField(max_length=20)
class CalendarModel(BaseModel):
name = models.CharField(max_length=20)
color = models.CharField(max_length=20)
event = models.ForeignKey(to=EventModel, on_delete=models.SET_NULL, null=True)
和 admin.py:
from django.contrib import admin
from .models import CalendarModel, EventModel
@admin.register(CalendarModel)
class CalendarAdmin(admin.ModelAdmin):
exclude = ['_id']
@admin.register(EventModel)
class EventAdmin(admin.ModelAdmin):
exclude = ['_id']
它适用于使用 SQLite 后端,并且在没有外键字段的 djongo 后端时可以正常工作,但是在使用djongo 后端并具有外键字段时给我一个错误。它说:
如上图所示,它可以从数据库中加载对象并正确检测关系,但无法保存。
而且我无法创建与另一个对象相关的新对象。我该如何解决这个问题?
更新
我可以使用这样的代码创建对象,问题似乎来自 Django 管理站点
e = EventModel.objects.first()
CalendarModel.objects.create(name="test", color="red", event=e)
解决方案
我注意到,当您尝试使用PK 保存对象的实例时 ObjectId将其转换为字符串,因此不再对应于对象的实例,因此通过覆盖POST中的get_form方法,您可以截获这个数据并将字符串更改为 ObjectId,但正如您在Django 文档中看到的那样:
request.POST和request.GET的QueryDict在正常的请求/响应周期中访问时将是不可变的。
因此您可以使用同一文档中的建议:
要获得可变版本,您需要使用QueryDict.copy()
或者......使用一个小技巧,例如,如果您出于某种原因需要保留对对象的引用或保持对象不变:
# remember old state
_mutable = data._mutable
# set to mutable
data._mutable = True
# сhange the values you want
data['param_name'] = 'new value'
# set mutable flag back
data._mutable = _mutable
哪里数据是你的QueryDicts
在这种情况下:
@admin.register(CalendarModel)
class CalendarModelAdmin(admin.ModelAdmin):
list_display = ('....')
....
def get_form(self, request, obj, change, **kwargs):
if request.POST:
# remember old state
_mutable = request.POST._mutable
# set to mutable
request.POST._mutable = True
# сhange the values you want
request.POST['event'] = ObjectId(request.POST['event'])
# set mutable flag back
request.POST._mutable = _mutable
return super().get_form(request, obj=obj, change=change, **kwargs)
推荐阅读
- r - 在 R 中对两个具有交叉连接的数据集使用 stringdist
- java - MapDB treemap.clear() 需要永远
- android - 有人能告诉我为什么这在 SQLITE 中是错误的吗
- javascript - 如何在 mongoOp 查找查询之外的节点 js 中打印结果数组?
- r - 用 NA 重新排列列
- c# - 如何应用 JsonExtensionData(字典
) 到另一个使用 JSON.Net 的对象 - python - 河内塔类型错误:“类型”对象不可下标
- python - Python3:如何重新设计嵌套类层次结构以更好地序列化和/或促进更好的模型/视图解耦
- android - Android 构建失败 - java.lang.IllegalArgumentException:对通配符的引用必须是数字 (*)
- php - 如何将 AWS IP 地址映射到域名以在 XAMPP Apache 服务器上运行 CodeIgniter Web 应用程序