假设我有三个相关模型 - 容器,类别和项目。每个模型都有两个字符串属性 - 名称和uuid(以及普通的“id”字段).uuid字段将用作SlugRelatedFields来表示REST接口中的关系。容器包含一组项目和一组类别;每个项目都与一个类别相关。
我想在一个POST中创建一个完整的容器(包含所有项目和类别)。但我似乎无法创建一个允许它的序列化器。当我尝试这样做时,当序列化程序尝试解码项时我收到错误 - 它发现引用的类别尚不存在。这并不奇怪,因为相同的POST将创建它。
以JSON形式,这是我想发布的内容:
{
"name": "My Container",
"uuid": "<container-uuid>",
"categories": [
{
"name": "Category One",
"uuid": "<category-one-uuid>",
}
],
"items": [
{
"name": "Item One",
"uuid": "<item-one-uuid>",
"category": "<category-one-uuid>",
},
{
"name": "Item Two",
"uuid": "<item-two-uuid>",
"category": "<category-one-uuid>",
}
]
}
因此,该示例将创建一个容器,一个类别和两个项目 - 这两个项目将与同一类别相关。
我可以在Item序列化程序中使用SlugRelatedField来通过uuid标识关联的Category。但在这种情况下,会引发错误:
Object with uuid=<category-one-uuid> does not exist.
反序列化“第一项”。可以理解,因为该类别尚未出现在数据库中。
有没有办法让这项工作?我可以覆盖ItemSerializer中的某个方法,使其查找正在反序列化的Container中的关联类别,而不是查看数据库中已存在的类别吗?我认为解决方案可能需要一些东西:
有什么想法吗?
更新2014-08-22:
我没有解决这个问题,但我已经解决了这个问题。解决方法是一个肮脏的黑客,涉及许多部分:
在模型中,我更改了外键引用的定义 从项目到类别允许NULL。
在Item的序列化程序中,我 将类别声明为一个简单的CharField(),而不是一个 SlugRelatedField通过其UUID标识类别。
在该序列化程序的“restore_object”方法中,我从类别字段中获取指定的UUID(在传递给该方法的“attrs”字典中)。我从该字典中删除该条目,并将一个条目添加到将Item UUID映射到关联的Category UUID的字典中。该字典保存在每个请求缓存中,如下所述:Per-request cache in Django?
然后我在item上有一个“pre_save”信号的处理程序,它在该字典中查找所需的类别UUID(使用Items的UUID作为键),在Category表上查询以查找正确的项目并使用它来设置foreignkey字段。
因此,当请求进入以创建具有关联项目和类别的新Container时:
答案 0 :(得分:0)
这是我的想法:
在那里,您应该找到一段像这样的代码:
if getattr(obj, '_nested_forward_relations', None):
# Nested relationships need to be saved before we can save the
# parent instance.
for field_name, sub_object in obj._nested_forward_relations.items():
if sub_object:
self.save_object(sub_object)
setattr(obj, field_name, sub_object)
我最好的猜测是,序列化程序会尝试保存嵌套对象(类别和项目)。