首页 > 解决方案 > 带有嵌套 json 和自定义键的 Django Restframework

问题描述

我正在使用带有 Restframework 的 Django。我试图以嵌套方式从序列化程序获取 json 输出,其中键作为模型中的字段之一。我实现了嵌套的 JSON,但它们的 json 键让我感到不安。

这是我的代码和预期的结果:

模型.py

class Tags(models.Model):
    tagId = models.CharField(primary_key=True, max_length=100, default=1)
    section = models.CharField(max_length=100,default=1)
    def __str__(self):
        return self.section

class TagItem(models.Model):
    section= models.ForeignKey(Tags, on_delete=models.CASCADE,default=1,related_name="items")
    select = models.BooleanField(default=False)
    name = models.CharField(max_length=50)
    def __str__(self):
        return self.name

序列化程序.py

class TagItemModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = TagItem
        fields = '__all__'


class TagModelSerializer(serializers.ModelSerializer):
    items = TagItemModelSerializer(many=True)

    class Meta:
        model = Tags
        fields = ['pk','section', 'items']

预期输出:

 {
    "crafts" : {                //craft is comming from Tag model's "section"
        "id": 1,
        "section": "crafts",
        "items": [
          {
            "id": "10",
            "select": false,
            "name": "Wood",   
            "category": "crafts"   
          },

        ]
      },
    "states" : {
        "id": 2,
        "section": "states",
        "items": [
          {
            "id": "20",
            "select": false,
            "name": "Andhra Pradesh",
            "category": "states" 
          }
        ]
      },
      "others" : {
      "id": 3,
      "section": "others",
      "items": [
        {
          "id": "30",
          "select": false,
          "name": "Volunteer",
          "category": "others" 
        }
      ]
    }
}

电流输出:

[                                           //cant get the key of Tag model's "section"
    {
        "pk": "1",
        "section": "states",
        "items": [
            {
                "id": 6,
                "select": false,
                "name": "Assam",
                "section": "1"
            }
        ]
    },
    {
        "pk": "2",
        "section": "others",
        "items": [
            {
                "id": 12,
                "select": false,
                "name": "Artisan",
                "section": "2"
            }
        ]
    },
    {
        "pk": "3",
        "section": "crafts",
        "items": [
            {
                "id": 9,
                "select": false,
                "name": "Metal",
                "section": "3"
            }
        ]
    }
]

标签: pythondjangodjango-rest-framework

解决方案


在你的情况下,你想有一个我认为的自定义表示?

您可以通过覆盖来调整它to_representation()

我提供了两种方法:

序列化器 -> 更好的方法,但不是你喜欢的输出

看法

class TagModelView(views.APIView):

    def get(self, request):
        qs = Tags.objects.all()
        serializer = TagModelSerializer(qs, many=True)
        return Response(data=serializer.data)

串行器

class TagItemModelSerializer(serializers.ModelSerializer):
    category = serializers.SerializerMethodField()

    class Meta:
        model = TagItem
        fields = ['id', 'select', 'name', 'category']

    def get_category(self, instance):
        return instance.section.section


class TagModelSerializer(serializers.ModelSerializer):
    items = TagItemModelSerializer(many=True)

    class Meta:
        model = Tags
        fields = ['pk', 'section', 'items']

    def to_representation(self, instance):
        container = super().to_representation(instance)
        return {container.get('section'): container}

在您的视图中进行表示 -> 您想要获得的输出

看法

    def get(self, request):
        qs = Tags.objects.all()
        serializer = TagModelSerializer(qs, many=True)

        container = dict()
        for element in serializer.data:
            container.update(**element)

        return Response(data=container)

串行器

我的建议没有改变。

更新

我看到您的主键TagstagId并且您正在使用fields = ['pk', 'section', 'items'],但您希望将其id作为键名。

重新标记可以帮助您。

class TagModelSerializer(serializers.ModelSerializer):
    items = TagItemModelSerializer(many=True)
    id = serializers.CharField(source='tagId')

    class Meta:
        model = Tags
        fields = ['id', 'section', 'items']

推荐阅读