如何为序列化程序正确使用嵌套关系?

时间:2019-07-01 16:19:49

标签: python django django-models django-rest-framework

我试图显示我的CatPerm中我的Category API端点内的任何数据。我的CatPerm数据由“ cat”,“ permission”和“ description”组成,它们分别是类别名称,权限和描述

每当我尝试外卖时:

    cat = serializers.SlugRelatedField(slug_field='name', read_only=True)
    permission = serializers.SlugRelatedField(slug_field='name', read_only=True)

从CatPermSerializer中,我将出现AttributeError: 尝试获取序列化程序cat上字段CatPermSerializer的值时,出现AttributeError。 序列化程序字段的名称可能不正确,并且与Permission实例上的任何属性或键都不匹配。 原始异常文本为:“权限”对象没有属性“猫”。

当前“类别” API端点的外观:

{
        "name": "Travel",
        "permission": [
            {
                "description": "Camera is used to take photos"
            }
        ]
    },

这是我想要的“类别” API端点外观:

{
        "name": "Travel",
        "permission": [
            {
                "cat": "Travel",
                "permission": "Internet",
                "description": "This is a description inside CatPerm"

            }
        ]
    },

models.py

class CatPerm(models.Model):
    cat = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='permissions')
    permission = models.ForeignKey(Permission, on_delete=models.CASCADE)
    description = models.TextField()


class Category(models.Model):
    name = models.CharField(max_length=50)
    permission = models.ManyToManyField(Permission,
                                        related_name='category_permissions',
                                        through='CatPerm'
                                        )


class Permission(models.Model):
    name = models.CharField(max_length=100)
    description = models.TextField()
    platform = models.CharField(
        max_length=10,
        choices=PLATFORM_CHOICES,
        default=BOTH,
    )
    classification = models.CharField(
        max_length=10,
        choices=CLASSIFICATION_CHOICES,
        default=LOW,
    )

serializer.py

class CatPermSerializer(serializers.ModelSerializer):
    cat = serializers.SlugRelatedField(slug_field='name', read_only=True)
    permission = serializers.SlugRelatedField(slug_field='name', read_only=True)

    class Meta:
        model = CatPerm
        fields = ("cat", "permission", "description")


class CategorySerializer(serializers.ModelSerializer):
    permission = CatPermSerializer(many=True, read_only=True)

    class Meta:
        model = Category
        fields = ("name", "permission")

1 个答案:

答案 0 :(得分:0)

如果要自定义响应,则可以覆盖to_representation()

class CategorySerializer(serializers.ModelSerializer):

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

    def to_representation(self, instance):
        data = super().to_representation(instance)
        # Here you can do whatever you need, for instance add different fields to response
        data['permissions'] = []
        for perm in instance.permissions.all():
            data['permissions'].append({'name': perm.name})
        return data