首页 > 解决方案 > Django多对多序列化程序反转嵌套的json表示

问题描述

在 Django 中,我使用 selected_related 来获取相关表数据的多对多关系。但是,相关表数据嵌套在每条记录中,我想反转关系,如果没有自定义序列化程序,这可能吗?

从:

[
  {
    "id": 1,
    "item": " Sub item",
    "parent_items": {
        "id": 1,
        "description": "Parent Item Number 1",
 }
},
{
    "id": 2,
    "item": " Sub item 2",
    "parent_items": {
        "id": 2,
        "description": "Parent Item Number 2",
 }
]

反转父关系:

[
  {
    "parent_items": ""Parent Item Number 1",
    "id": 1,   
    "item": {
        "id": 1,
        "description": "Sub Item 1",
      }, 
     { 
     "item": {
        "id": 2,
        "description": "Sub Item 2 ",
  },

},
{  
    "parent_items": " Parent Item Number 2",
    "id": 2,

    "item": {
        "id": 1,
        "description": "SubItem Item 2",
  }  ............

]

这里是序列化器、模型和视图。

模型:

class MainItem(models.Model):
   id = models.IntegerField(primary_key=True)
   description = models.CharField(max_length=50) 

class SubItem(models.Model):
  """Equates to parent items"""
  id = models.IntegerField(primary_key=True) 
  main_item = models.ForeignKey(MainItem, null=False)
  description = models.CharField(max_length=50) 


 class Main(models.Model):
  id = models.AutoField(primary_key=True)
  href = models.CharField(max_length=250)
  sub_items = models.ManyToManyField(SubItem)

序列化器:

class SubItemSerializer(ModelSerializer):
    class Meta:
        model = SubItem
        fields = '__all__'
        depth = 1

风景:

class ItemsView(APIView):
      def get(self, request):

      items = SubItems.objects.select_related('main_item').all()
      issue_ser = SubItemSerializer(issues, many=True)

      return Response(issue_ser.data)

标签: djangodjango-rest-frameworkmany-to-many

解决方案


您应该重写代码以使其基于MainItem而不是SubItem.

请注意,您可以使用 MainItemsubitem_set属性获取所有相关子项。<modelname>_set是 Django 中多对一关系的默认反向相关名称。

所以尝试这样的事情:

class MainItemSerializer(ModelSerializer):
    class Meta:
        model = MainItem
        fields = ('id', 'description', 'subitem_set')
        depth = 1

class ItemsView(APIView):
      def get(self, request):
          items = MainItem.objects.prefetch_related('subitem_set').all()
          issue_ser = MainItemSerializer(issues, many=True)

          return Response(issue_ser.data)

推荐阅读