在使用Django的--natural选项转储模型到fixture时,可能会遇到Content_typ ID问题。
例如,假设有一个名为OpportunityMetaDataModel的模型,它包含一个_content_type字段,该字段存储了模型的Content_type ID。当使用--natural选项转储OpportunityMetaDataModel模型时,结果是:
{
"pk": 1,
"model": "seo.opportunitymetadatamodel",
"fields": {
"_content_type": [
"opportunity",
"jobopportunity"
],
"og_description": "",
"description": "",
"title": "test",
"keywords": "",
"og_title": "",
"heading": ""
}
}
当尝试加载此fixture时,可能会遇到以下错误:
Problem installing fixture 'seo/fixtures/initial_data.json': Traceback (most recent call last):
File "/Users/xx/dev/envs/xx/lib/python2.6/site-packages/django/core/management/commands/loaddata.py", line 167, in handle
for obj in objects:
File "/Users/xx/dev/envs/xx/lib/python2.6/site-packages/django/core/serializers/json.py", line 38, in Deserializer
for obj in PythonDeserializer(simplejson.load(stream), **options):
File "/Users/xx/dev/envs/xx/lib/python2.6/site-packages/django/core/serializers/python.py", line 84, in Deserializer
Model = _get_model(d["model"])
TypeError: string indices must be integers, not str
- 解决方案 为了解决此问题,需要将模型包装在一个列表中,如下所示:
[ { "pk": 1, "model": "seo.opportunitymetadatamodel", "fields": { "_content_type": [ "opportunity", "jobopportunity" ],
"og_description": "",
"description": "",
"title": "test",
"keywords": "",
"og_title": "",
"heading": ""
}
}
]
>>> d = [{... "pk": 1, ... "model": "seo.opportunitymetadatamodel", ... "fields": {... "_content_type": [... "opportunity", ... "jobopportunity"... ],
... "og_description": "",
... "description": "",
... "title": "test",
... "keywords": "",
... "og_title": "",
... "heading": ""
... }
... }]
>>> import json
>>> json.dumps(d)
'[{"pk": 1, "model": "seo.opportunitymetadatamodel", "fields": {"_content_type": ["opportunity", "jobopportunity"], "og_description": "", "description": "", "title": "test", "keywords": "", "og_title": "", "heading": ""}}]'
当Django解析JSON数据时,它会将数据传递给python反序列化器。反序列化器按如下方式迭代数据:
for d in object_list:
# Look up the model and starting build a dict of data for it.
Model = _get_model(d["model"])
如果object_list是一个json对象,迭代只会获取键,在这种情况下可能是pk、model和field。在第84行,Django执行_get_model(d["model"]),即使用字符串“model”作为另一个字符串(可能是object_list中的第一个元素pk)的索引。这是一个类型错误。
当object_list是一个实际列表时,迭代它将返回字典,这些字典可以通过字符串索引。