python - 带有嵌套 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"
}
]
}
]
解决方案
在你的情况下,你想有一个我认为的自定义表示?
您可以通过覆盖来调整它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)
串行器
我的建议没有改变。
更新
我看到您的主键Tags
是tagId
并且您正在使用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']
推荐阅读
- android - 如果有的话,Subcompose Layout 什么时候支持 Intrinsic 布局?
- python - 矢量化二次公式,为什么仍然会引发 numpy.sqrt() 中的运行时警告无效值?
- python - 如何确定 pyd 文件中缺少哪个 DLL?
- ios - ViewDidLoad tableViewCell alpha 问题?
- google-apps-script - 如何防止查看器使用应用程序脚本从共享的谷歌电子表格中获取值,尤其是对于隐藏的表格
- java - 如何找到二维数组中索引为 0 或 1 的二维形状的周长和面积?
- c++ - 如果使用 CRTP,派生类方法是否会覆盖该方法的基类版本?
- c++ - 为什么我必须在这种情况下参考?
- hashicorp-vault - Vault kv put/write 二进制数据
- amazon-web-services - 在 terraform IPSec 隧道中使用的 AWS IP 地址(通过 Transit Gateway)