繁体   English   中英

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

[英]django-rest-framework: How to serialize join of database models?

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

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来使用单个Serializer进行此操作

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,而在获取项目时使用嵌套序列化程序。 例如。

POST:

{
    "product": 10,
    ...
}

得到:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM