django-rest-framework:如何序列化数据库模型的连接



我正在从事一个简单的项目,用于从模型定义如下的网站销售产品:

class Product(models.Model):
    """
        Model for Products
    """
    price = models.FloatField()
    description = models.TextField()
    url = models.CharField(max_length=200)
    def __str__(self):
        return self.description
class Order(models.Model):
    """
    Model for Orders
    """
    UNPAID = 0
    PAID = 1
    FAILED = 2
    STATUS = (
        (UNPAID, 'UNPAID'),
        (PAID, 'PAID'),
        (FAILED, 'FAILED'),
    )
    user = models.ForeignKey(User)
    product = models.ForeignKey(Product)
    orderdate = models.DateTimeField()
    token = models.CharField(max_length=30)
    paymentstatus = models.IntegerField(choices=STATUS)

相应地,序列化程序定义如下:

class ProductSerializer(serializers.ModelSerializer):
    """
    Serialize Product list
    """
    class Meta:
        """
        Metadata for Product Serializationt to expose API
        """
        model = Product
        fields = ('id', 'price', 'description', 'url')
class OrderSerializer(serializers.ModelSerializer):
    """
    Serialize Order of Product
    """
    class Meta:
        """
        Order metadata
        """
        model = Order
        fields = ('id', 'user', 'orderdate', 'token', 'paymentstatus',
                  'product')

class OrderDetailSerializer(serializers.ModelSerializer):
    """
    Serialize Order Details
    """
    product = ProductSerializer(read_only=True)
    class Meta:
        """
        Order metadata
        """
        model = Order
        fields = ('id', 'user', 'orderdate', 'paymentstatus', 'product')

在上面的例子中,是否可以将OrderSerializerOrderDetailsSerializer组合成一个序列化程序?

当用户放置新Order即写入数据库并OrderDetailSerializer从数据库中获取订单的详细信息时,我使用该OrderSerializer

可以通过使用自定义字段并使令牌write_only来使用单个序列化程序执行此操作

class ProductSerializer(serializers.ModelSerializer):
    """
    Serialize Product list
    """
    class Meta:
        """
        Metadata for Product Serializationt to expose API
        """
        model = Product
        fields = ('id', 'price', 'description', 'url')
class ProductField(serializers.PrimaryKeyRelatedField):
    def to_representation(self, value):
        id = super(ProductField, self).to_representation(value)
        try:
          product = Product.objects.get(pk=id)
          serializer = ProductSerializer(product)
          return serializer.data
        except Product.DoesNotExist:
            return None
    def get_choices(self, cutoff=None):
        queryset = self.get_queryset()
        if queryset is None:
            return {}
        return OrderedDict([(item.id, self.display_value(item)) for item in queryset])
class OrderSerializer(serializers.ModelSerializer):
    """
    Serialize Order of Product
    """
    product = ProductField(queryset=Product.objects.all())
    class Meta:
        """
        Order metadata
        """
        model = Order
        fields = ('id', 'user', 'orderdate', 'token', 
                  'paymentstatus', 'product')
        extra_kwargs = {'token': {'write_only': True}}

自定义字段将允许您在发布时使用模型 ID,同时在获取项目时获取嵌套序列化程序。

发布:

{
    "product": 10,
    ...
}

获取:

{
    "product": {
        "url": "http://localhost:8000/..."
        "price": "$2.50",
        ...
    }
    ...
}

最新更新