首页 > 解决方案 > 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())

我是从错误的角度看待这个问题吗?还是我的模型架构不适合这个?如果没有,我做错了什么

标签: jsondjangodatabaseapidjango-rest-framework

解决方案


我想我找到了一个解决方案,可以解决我的所有问题,它不是最优化的,如果有人可以分享一个更好的,我很乐意检查一下,但这里是:

我选择了厚视图而不是厚序列化程序,我保持模型原样,使用 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)

我期待解决问题的任何改进或其他答案。


推荐阅读