Django rest框架嵌套自引用对象 [英] Django rest framework nested self-referential objects

查看:17
本文介绍了Django rest框架嵌套自引用对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的模型看起来像这样:

I have model that looks like this:

class Category(models.Model):
    parentCategory = models.ForeignKey('self', blank=True, null=True, related_name='subcategories')
    name = models.CharField(max_length=200)
    description = models.CharField(max_length=500)

我设法用序列化器获得了所有类别的平面 json 表示:

I managed to get flat json representation of all categories with serializer:

class CategorySerializer(serializers.HyperlinkedModelSerializer):
    parentCategory = serializers.PrimaryKeyRelatedField()
    subcategories = serializers.ManyRelatedField()

    class Meta:
        model = Category
        fields = ('parentCategory', 'name', 'description', 'subcategories')

现在我想做的是让子类别列表具有子类别的内联 json 表示,而不是它们的 id.我将如何使用 django-rest-framework 来做到这一点?我试图在文档中找到它,但似乎不完整.

Now what I want to do is for subcategories list to have inline json representation of subcategories instead of their ids. How would I do that with django-rest-framework? I tried to find it in documentation, but it seems incomplete.

推荐答案

不要使用 ManyRelatedField,而是使用嵌套的序列化器作为你的字段:

Instead of using ManyRelatedField, use a nested serializer as your field:

class SubCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ('name', 'description')

class CategorySerializer(serializers.ModelSerializer):
    parentCategory = serializers.PrimaryKeyRelatedField()
    subcategories = serializers.SubCategorySerializer()

    class Meta:
        model = Category
        fields = ('parentCategory', 'name', 'description', 'subcategories')

如果你想处理任意嵌套的字段,你应该看看 自定义默认字段 文档的一部分.您目前不能直接将序列化程序声明为自身的字段,但您可以使用这些方法来覆盖默认使用的字段.

If you want to deal with arbitrarily nested fields you should take a look at the customising the default fields part of the docs. You can't currently directly declare a serializer as a field on itself, but you can use these methods to override what fields are used by default.

class CategorySerializer(serializers.ModelSerializer):
    parentCategory = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = Category
        fields = ('parentCategory', 'name', 'description', 'subcategories')

        def get_related_field(self, model_field):
            # Handles initializing the `subcategories` field
            return CategorySerializer()

<小时>

实际上,正如您所指出的,上述内容并不完全正确.这有点小技巧,但您可以尝试在序列化程序已经声明后添加该字段.


Actually, as you've noted the above isn't quite right. This is a bit of a hack, but you might try adding the field in after the serializer is already declared.

class CategorySerializer(serializers.ModelSerializer):
    parentCategory = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = Category
        fields = ('parentCategory', 'name', 'description', 'subcategories')

CategorySerializer.base_fields['subcategories'] = CategorySerializer()

需要添加一种声明递归关系的机制.

A mechanism of declaring recursive relationships is something that needs to be added.

编辑:请注意,现在有一个第三方包可以专门处理这种用例.请参阅 djangorestframework-recursive.

Edit: Note that there is now a third-party package available that specifically deals with this kind of use-case. See djangorestframework-recursive.

这篇关于Django rest框架嵌套自引用对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆