簡體   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