首页 > 解决方案 > 如何使用序列化程序以嵌套方式从 django 模型中检索数据?

问题描述

我有一个包含 3 个字段的 django 模型:“product”、“price_1”和“price_2”。

我想以某种方式序列化这个模型,结果是:

{
   "product": "some product",
   "price": {
      "price_1": 15.00,
      "price_2": 25.00
   }
}

我可以通过为价格创建一个模型并使用外键将其连接到产品模型来达到这个结果。

#Models

class Product(models.Model):
   product = models.CharField()
   price = models.ForeignKey(Price)

class Price(models.Model):
   price_1 = models.FloatField()
   price_2 = models.FloatField()

#Serializers

class PriceSerializer(serializers.ModelSerializer):
   class Meta:
      model = Price
      fields = ['price_1', 'price_2']

class ProductSerializer(serializers.ModelSerializer):
   price = PriceSerializer()

   class Meta:
      model = Product
      fields = [
         "product", 
         "price",
      ]

它奏效了,但是非常无效。有没有办法让我达到相同的结果,但只有一个模型,例如:

class Product(models.Model):
   product = models.CharField()
   price_1 = models.FloatField()
   price_2 = models.FloatField()

如果我只能有没有“价格”这个词的数字,那就更好了:

{
   "product": "some product",
   "price": {
      1: 15.00,
      2: 25.00
   }
}

虽然第二个结果更好,但如果我只使用一个模型就可以实现第一个,我已经很高兴了。

提前致谢!

编辑:

这是我正在使用的视图:

class ProductReadAPIView(generics.RetrieveAPIView):
    lookup_field = 'pk'
    serializer_class = ProductSerializer

    def get_queryset(self):
        return Product.objects.all()

标签: pythondjangodjango-modelsdjango-rest-framework

解决方案


您可以使用source[DRF docs]参数将整个对象传递给嵌套序列化程序,该序列化程序仅处理价格字段来执行此操作。

型号

class Product(models.Model):
   product = models.CharField()
   price_1 = models.FloatField()
   price_2 = models.FloatField()

序列化器

class ProductPriceSerializer(serializers.ModelSerializer):
   class Meta:
      model = Product
      fields = ['price_1', 'price_2']


class ProductSerializer(serializers.ModelSerializer):
   price = ProductPriceSerializer(source='*')

   class Meta:
      model = Product
      fields = [
         "product",
      ]

获取12作为键会有点困难,我不会这样做,因为它会有点 hacky。但更进一步,您的模型架构(两者)似乎没有标准化,实际上最好有不同的模型,以防您有多个价格要处理,下面的代码会更好地为您的用例建模:

class Product(models.Model):
   product = models.CharField()


class Price(models.Model):
   price = models.ForeignKey(Product)
   price = models.FloatField()  # use a DecimalField instead for prices!

推荐阅读