json - DRF 嵌套对象序列化和创建
问题描述
我试图通过获取一个嵌套了对象的 json 来创建对象,例如,我有一个模型,其中只有一个字段是 name,我得到了这个 json
{"name":"category1",
"children":[{
"name":"category1.1",
"children":[]},
{"name":"category1.2",
"children":[{"name":"category1.2.1",
"children":[]}]
}
]
}
我想要实现的是阅读这个,并创建引用其父级或子级的类别对象,我尝试了多种受这些答案启发的解决方案,但我似乎无法接近完成工作(Django rest 框架嵌套的自引用对象——如何在 DRF 中用一个请求创建多个对象(相关)?)
我已经尝试让模型只有名称和引用类别本身的外键,并且我将递归字段添加到我的序列化程序中,如下所示:
class RecursiveField(serializers.Serializer):
def to_representation(self, value):
serializer = self.parent.parent.__class__(value, context=self.context)
return serializer.data
class CategorySerializer(serializers.ModelSerializer):
subcategories = RecursiveField(many=True,allow_null=True)
class Meta:
model = Category
fields = ['name','subcategories']
def create(self, validated_data):
category = None
if len(validated_data['subcategories'])==0:
category = Category.objects.create(name=validated_data['name'])
else:
for i in range(len(validated_data['subcategories'])):
child = validated_data['subcategories']
child_list = list(child.items())
subcat = child_list[1]
if len(subcat)==0:
subcategory = Category.objects.create(name=child.get('name'))
category = Category.objects.create(name=validated_data['name'],children=subcategory)
return category
我用这个解决方案得到的最好的结果是能够创建父对象,但是我无法获取子对象,而是得到了一个空的 OrderedDict() (我只尝试了这个解决方案来查看我是否可以访问子对象但是显然我不能,我在子变量中得到一个空的 OrderedDict())
我是从错误的角度看待这个问题吗?还是我的模型架构不适合这个?如果没有,我做错了什么
解决方案
我想我找到了一个解决方案,可以解决我的所有问题,它不是最优化的,如果有人可以分享一个更好的,我很乐意检查一下,但这里是:
我选择了厚视图而不是厚序列化程序,我保持模型原样,使用 2 个字段、名称字段和引用父级的外键,至于序列化程序:
class CategorySerializer(serializers.Serializer):
name = serializers.CharField()
children = serializers.ListField()
我仍然需要为列表字段添加验证器,至于视图,我使用了一个遍历所有子项并添加它们的递归函数:
def post(self,request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
parent = serializer
#creating the parent object
category = Category.objects.create(name=parent.validated_data['name'])
#saving the parent object's id
parent_id = category.id
#Checking if the item has children
children = parent.validated_data['children']
#if the parent doesn't have children nothing will happen
if children == None:
pass
#Call the recursion algorithm to create all the children
else:
self.recursion_creation(children,parent_id)
return Response({
"id":parent_id,
})
def recursion_creation(self,listOfChildren,parentId):
#This will go through all the children of the parent and create them,and create their children
for k in range(len(listOfChildren)):
name = listOfChildren[k].get("name")
#create the child
category = Category.objects.create(name=name,parent_id=parentId)
categoryId = category.id
#save it's id
children = listOfChildren[k].get("children")
#if this child doesn't have children the recursion will stop
if children==None:
pass
#else it will apply the same algorithm and goes through it's children and create them and check their children
else:
self.recursion_creation(children,categoryId)
我期待解决问题的任何改进或其他答案。
推荐阅读
- html - Bootstrap 4 - 两张重叠的卡片之间的 div
- php - 确定对象中是否存在数组。php
- flutter - 如何使用 intellij Dart 插件在 dart 中创建新语句
- php - 我们如何使用带有多个参数的 laravel URL?是否需要将每个参数指定为方法参数?不能通过Request访问它们吗?
- postgresql - 如何从 PostgreSQL c 扩展函数返回 jsonb 对象?
- matlab - 加速向量求和
- javascript - 比想要的时间增加更多的时刻
- javascript - 为什么我的函数无意中执行了两次?
- image - 从 Tensorflow 中的图像张量中提取随机不重叠的补丁
- sql - 如何根据分数选择表格中的前5名学生