DRF嵌套对象的序列化和创建

时间:2020-06-13 14:34:16

标签: json django database api django-rest-framework

我试图仅通过获取嵌套了对象的json来创建对象,例如,我有一个仅包含一个名为name的字段的模型,而我正在获取此json

{"name":"category1",
"children":[{
   "name":"category1.1",
   "children":[]},
   {"name":"category1.2",
   "children":[{"name":"category1.2.1",
                "children":[]}]
}
]
}

我要实现的目的是阅读本文,并创建引用其父代或子代的类别对象, 我已经尝试了从这些答案中获得启发的多种解决方案,但似乎离完成工作还差得远(Django rest framework nested self-referential objects-How to create multiple objects (related) with one request in 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())

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

1 个答案:

答案 0 :(得分:0)

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

我去了厚实的视图而不是厚厚的序列化程序,我保留了模型,它保留了两个字段,即名称字段和引用父级的外键,就像序列化程序一样:

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)

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