Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angularjs 在给定嵌套对象时仅更新ForeignKey引用_Angularjs_Django_Nested_Django Rest Framework_Serialization - Fatal编程技术网

Angularjs 在给定嵌套对象时仅更新ForeignKey引用

Angularjs 在给定嵌套对象时仅更新ForeignKey引用,angularjs,django,nested,django-rest-framework,serialization,Angularjs,Django,Nested,Django Rest Framework,Serialization,我在我认为应该是一个简单的模式上停留了一段时间。因此,我将在这里分享我是如何为遇到同样问题的其他人解决这个问题的。也许有些人也会提出更好的解决方案 API使用Django Rest框架,前端使用Angular 1.5 挑战: 包括有关个人家庭的详细(嵌套)信息以及个人记录,以避免额外的网络往返,并能够更改个人所属的家庭 默认情况下,DRF乐意提供来自相关模型的嵌套信息。但是如果你改变了它,它就不太乐意把它拿回去 Angular很乐意显示资源的嵌套信息,但其默认操作是在更新时以完全相同的嵌套格式发

我在我认为应该是一个简单的模式上停留了一段时间。因此,我将在这里分享我是如何为遇到同样问题的其他人解决这个问题的。也许有些人也会提出更好的解决方案

API使用Django Rest框架,前端使用Angular 1.5

挑战: 包括有关个人家庭的详细(嵌套)信息以及个人记录,以避免额外的网络往返,并能够更改个人所属的家庭

默认情况下,DRF乐意提供来自相关模型的嵌套信息。但是如果你改变了它,它就不太乐意把它拿回去

Angular很乐意显示资源的嵌套信息,但其默认操作是在更新时以完全相同的嵌套格式发回所有资源数据

以下是无法正常工作的DRF设置:

#模型
家庭类别(型号.型号):
完整地址=models.CharField(最大长度=200,空白=真,默认值=“”)
班级负责人(models.Model):
家用=型号。外键(
“家庭,家庭”,
空=真,
相关人员(姓名=“人员”)
全名=models.CharField(最大长度=100)
#观点
类别HouseholdViewSet(ModelViewSet):
模型=家庭
queryset=househouse.objects.all()
serializer\u class=HouseholdSerializer
类PersonViewSet(ModelViewSet):
模特=人
queryset=Person.objects.all()
序列化程序\u类=PersonSerializer
#序列化程序
类HouseholdSerializer(serializers.ModelSerializer):
类元:
模型=家庭
类PersonSerializer(serializers.ModelSerializer):
Househouse=HouseholdSerializer(many=False,read\u only=True)
类元:
模特=人
字段=('id','Househous','full_name',)
当angular获取person资源时,家庭id和完整地址被嵌套,这样“家庭”现在是一个对象,而不是主键

{
“id”:42,
“全名”:“丽莎·亚当斯”,
“家庭”:{
“id”:17,
“完整地址”:“斯普林菲尔德大街123号,邮编55555”
}
}
当Lisa离开家,与她的新室友搬到另一个家庭时,用户将该家庭更改为另一个现有地址,并发送PUT请求。服务器200响应指示成功,但新家庭未持久化到数据库。因此,如果用户再次查看个人记录,它仍然有旧的家庭

这是在person序列化程序中将Househouse字段设置为只读的结果。DRF以静默方式忽略嵌套对象

但如果更改为read_only=False,DRF坚持必须包含显式的.update()

AssertionError:`.update()`方法不支持可写
默认情况下,nestedfields。为序列化程序编写显式的“.update()”方法
我花了一段时间编写了一个自定义更新函数,但没能让它正常工作。我不需要更新嵌套信息中的任何内容。我只是需要把参考资料改成不同的家庭记录。所有的例子似乎都比需要的复杂,我从来没有让自定义update()用于这个简单的用例

当然,更新对外国记录的引用是一件很平常的事情,即使该记录的细节已经存在。但我没有找到任何正式记录的示例,我只是在尝试修改SO和博客上的示例时,在几个小时内坚持遗漏一个或另一个细节。

解决方案: 由于DRF很乐意在没有任何嵌套细节的情况下对“Househouse”进行更改引用,因此我将“Househouse”字段作为主键保留不变,从而解决了更新它的问题。然后,我在PersonSerializer中添加了一个新字段“Househouse_details”,以在新名称空间中提供详细信息

类PersonSerializer(serializers.ModelSerializer):
household\u details=HouseholdSerializer(many=False,read\u only=True,source='household')
类元:
模特=人
字段=(“id”、“住户”、“住户详细信息”、“全名”)
这将在同一“家庭”模型上创建一个新的字段点,但由于它是只读的,DRF将在angular提交回时忽略它

然后,我只需要将角度控制器稍微复杂化,以便在更新时读取“Househouse_details”字段,并使用“Househouse_details”中的id字段写入“Househouse”字段


功能更新(新的家庭细节){
vm.person.househouse=新的_househouse_detail.id;
vm.person.$update(函数(){
toastr.success('Updated'+vm.person.full_name+'Successfully');
},函数(错误响应){
toastr.error('Failed:'+errorResponse.data.message);
});
}
注意:这段代码都是从我的工作代码中简化出来的。我没有确认它是否有效。但这里的概念应该更清楚。以这种形式写下来有助于我在脑海中巩固解决方案。我希望它能帮助其他人在这里使用。

解决方案: 由于DRF很乐意在没有任何嵌套细节的情况下对“Househouse”进行更改引用,因此我将“Househouse”字段作为主键保留不变,从而解决了更新它的问题。然后,我在PersonSerializer中添加了一个新字段“Househouse_details”,以在新名称空间中提供详细信息

类PersonSerializer(serializers.ModelSerializer):
household\u details=HouseholdSerializer(many=False,read\u only=True,source='household')
类元:
模特=人
字段=(“id”、“住户”、“住户详细信息”、“全名”)
这将在同一“家庭”模型上创建一个新的字段点,但由于它是只读的,DRF将在angular提交回时忽略它

然后,我不得不把我的角度控制器复杂化一点,以便阅读“家庭细节”
class PersonSerializer(serializers.ModelSerializer):
    household = HouseholdSerializer(read_only=True)
    household_id = serializers.IntegerField()

    class Meta:
        model = Person
        fields = ('id', 'household', 'household_id', 'full_name',)