Javascript 如何使用Django REST框架保存嵌套主干模型
我正在尝试快速射击保存一系列外键相关的物品。保存父项后,我在创建子项时使用返回的父项id 这可以工作一两次,但在第二次或第三次,我得到的信息是:Javascript 如何使用Django REST框架保存嵌套主干模型,javascript,python,django,backbone.js,django-rest-framework,Javascript,Python,Django,Backbone.js,Django Rest Framework,我正在尝试快速射击保存一系列外键相关的物品。保存父项后,我在创建子项时使用返回的父项id 这可以工作一两次,但在第二次或第三次,我得到的信息是: {“parent_id”:[“无效pk\”5063\“-对象不存在。”]} 我已核实: 发送用于创建相关项的ID实际上与保存父项后在done()中返回的ID相同 如果在创建子项之前添加延迟,则可以检入数据库并验证父项是否确实已创建并保存到数据库中 如果在创建子项之前添加足够长的延迟(~15秒),则不会产生错误 由于Backbone.js前端似乎正
{“parent_id”:[“无效pk\”5063\“-对象不存在。”]}
我已核实:
- 发送用于创建相关项的ID实际上与保存父项后在
中返回的ID相同done()
- 如果在创建子项之前添加延迟,则可以检入数据库并验证父项是否确实已创建并保存到数据库中
- 如果在创建子项之前添加足够长的延迟(~15秒),则不会产生错误
var i=0;
函数createNew(){
var parent=ParentObjects.add({name:“新父项”});
parent.save().done(函数(变量属性、填充、填充){
var id=attributes.id;
var child=ChildObjects.add({name:“New child Item”,parent_id:id});
child.save().done(函数()){
i++;
如果(i<10){
createNew();
}
});
});
}
Django Rest框架代码
数据库是Postgresql。第一个请求成功,但尚未进入数据库,可能只是在该请求线程的缓存中,似乎发生了竞争条件。然后一个后续调用到达,创建另一个线程来处理它,但是父线程还没有真正在数据库中,所以它失败了
如何使用主干保存嵌套模型?
主干网的经验法则是:不要一个接一个地将请求循环到API。
而是将整个对象发送到API外键是一个关系数据库概念,您应该尽量避免在前端执行数据库/后端工作
例如,父级的属性
可用于同时创建父级及其子级:
ParentObjects.create({
名称:“新父项”,
儿童:[
{name:“新建子项”}
]
});
后端应返回:
{
id: "23",
name: "New Parent Item",
children: [
{ id: "35", name: "New Child Item", parent: "23" }
]
}
如何使用Django REST Framework(DRF)保存嵌套模型?
从第3版开始,DRF就提供了这样的功能,所以它几乎可以与上面的主干示例一起开箱即用。您只需要为子模型字段提供序列化程序,并重写create
方法
下面是一个文档示例,其中包含一个简单的关系
用户谢谢!这似乎是一个很好的替代方案。我仍然不明白为什么会发生这种情况,因为当我在保存子项之前添加5秒的延迟,并检查数据库中的父表时,新的父项就在那里,但保存子项仍然失败,就好像不存在这样的父项一样。@ZacharyBlackwood很难说为什么会发生这种情况,可能是某个地方的配置或Django优化,在实际保存之前做出响应。将整个存储放在一个请求中将大大简化调试。此外,最好的感谢是Upvots;)
{
id: "23",
name: "New Parent Item",
children: [
{ id: "35", name: "New Child Item", parent: "23" }
]
}
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ('username', 'email', 'profile')
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(**validated_data)
Profile.objects.create(user=user, **profile_data)
return user