1. 程式人生 > 實用技巧 >序列化(模型序列化、序列化巢狀)

序列化(模型序列化、序列化巢狀)

模型序列化

from rest_framework import serializers
from meituan.models import Merchant,

class MerchantSerializer(serializers.ModelSerializer):
    class Meta:
        model = Merchant
        # 要展示的欄位列表,為“__all__”時則全部展示
        fields = "__all__"
        # 定義不展示哪些欄位
        # exclude = ['name']

序列化巢狀

  • 使用場景
    當查詢的model裡有外來鍵時,又想在取該model資料時將對應的外來鍵表中的資料同時取出時使用。
  • 使用方法
    定義序列化類時,指定外來鍵的欄位使用哪個序列化類(因此,需要提前將外來鍵表的序列化類寫好)。
    • read_only : 表示只有在查詢資料時,才會使用到該欄位的序列化類,在其他情況時,不執行該序列化類
    • write_only : 表示只有在寫的時候,才會執行的序列化類。因為orm的外來鍵在生成資料庫時會自動建立成filedname_id的形式,所以在指定寫時,應該也指定成該形式。
    • many :當返回的是多條資料時,需要指定 many=True 。確定取出的是單條資料時,不用設定,因為其預設為False
    • 當建立有外來鍵資料的model資料時,需要自己複寫create方法。
class Merchant(models.Model):
    """
    商家
    """
    name = models.CharField(max_length=200,verbose_name='商家名稱',null=False)
    address = models.CharField(max_length=200,verbose_name='商家',null=False)
    logo = models.CharField(max_length=200,verbose_name='商家logo',null=False)
    notice = models.CharField(max_length=200, verbose_name='商家的公告',null=True,blank=True)
    up_send = models.DecimalField(verbose_name='起送價',default=0,max_digits=6,decimal_places=2)
    lon = models.FloatField(verbose_name='經度')
    lat = models.FloatField(verbose_name='緯度')

    created = models.ForeignKey(User,on_delete=models.SET_NULL,null=True)


class GoodsCategory(models.Model):
    """
    商家商品分類
    """
    name = models.CharField(max_length=20,verbose_name='分類名稱')
    merchant = models.ForeignKey(Merchant,on_delete=models.CASCADE,verbose_name='所屬商家',related_name='categories')
from rest_framework import serializers
from meituan.models import Merchant,GoodsCategory,Goods

class MerchantSerializer(serializers.ModelSerializer):
    class Meta:
        model = Merchant
        # 要展示的欄位列表,為“__all__”時則全部展示
        fields = "__all__"
        # 定義不展示哪些欄位
        # exclude = ['name']

class GoodsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Goods
        fields = "__all__"

class GoodsCategorySerializer(serializers.ModelSerializer):
    merchant = MerchantSerializer(read_only=True)
    merchant_id = serializers.IntegerField(write_only=True)
    goods_list = GoodsSerializer(many=True,read_only=True)
    class Meta:
        model = GoodsCategory
        fields = "__all__"

    def validate_merchant_id(self,value):
        if not Merchant.objects.filter(pk=value).exists():
            raise serializers.ValidationError("商家不存在!")
        return value

    def create(self,validated_data):
        merchant_id = validated_data.get('merchant_id')
        merchant = Merchant.objects.get(pk=merchant_id)
        category = GoodsCategory.objects.create(**validated_data,merchant=merchant)
        return category