序列化器嵌套序列化器,重寫序列化器create和update方法與使用事務保存數據


序列化器嵌套序列化器

規格表序列化器

class SKUSpecificationSerialzier(serializers.ModelSerializer):
    """
        SKU規格表序列化器
    """
    spec_id = serializers.IntegerField()
    option_id = serializers.IntegerField()
    class Meta:
        model = SKUSpecification  # SKUSpecification中sku外鍵關聯了SKU表
        fields = ("spec_id", 'option_id')

商品表序列化器

class SKUSerializer(serializers.ModelSerializer):
  #增加外鍵的字段 spu_id
= serializers.IntegerField() category_id = serializers.IntegerField() spu = serializers.StringRelatedField(read_only=True) category = serializers.StringRelatedField(read_only=True)   
  #實現序列化器的嵌套
specs
= SKUSpecificationSerialzier(many=True) class Meta: model=SKU fields='__all__'

重寫序列化器create和update方法

默認情況下,嵌套串行器是只讀的。如果要支持對嵌套序列化器字段的寫操作,則需要創建create()和/或update()方法,以明確指定應如何保存子關系。

def create(self, validated_data):
        # 獲取規格信息,並從validated_data數據中,刪除規格信息數據
        specs_data = validated_data.pop('specs')
        # 保存sku
        sku = SKU.objects.create(**validated_data)
        # 對規格信息進行遍歷,來保存商品規格信息
        for spec_data in specs_data:
            SKUSpecification.objects.create(sku=sku, **spec_data)
        # 返回sku
        return sku
    def update(self, instance, validated_data):
    # 獲取規格信息,並從validated_data數據中,刪除規格信息數據
    specs_data = validated_data.pop('specs')

    # 方案一: 調用父類 ,去實現沒有問題的數據更新
    super().update(instance,validated_data)

    # 方案二
    #獲取pk
    # pk = self.context['view'].kwargs.get('pk')
    # #更新數據
    # SKU.objects.filter(id=pk).update(**validated_data)

    # 方案三 把父類的源碼 拿來
    # for attr, value in validated_data.items():
    #     setattr(instance, attr, value)
    # instance.save()

    # 對規格信息進行遍歷,來保存商品規格信息
    for spec_data in specs_data:
        # item {spec_id: "4", option_id: 8}
        SKUSpecification.objects.filter(sku=instance,
                                        spec_id=spec_data.get('spec_id')). \
            update(option_id=spec_data.get('option_id'))

    return instance

使用事務保存數據

def create(self, validated_data):
        # 獲取規格信息,並從validated_data數據中,刪除規格信息數據
        specs_data = validated_data.pop('specs')

        with transaction.atomic():
            # 開啟事務
            savepoint = transaction.savepoint()
            # 保存sku
            sku = SKU.objects.create(**validated_data)
            # 對規格信息進行遍歷,來保存商品規格信息
            for spec_data in specs_data:
                SKUSpecification.objects.create(sku=sku, **spec_data)
            # 清除保存點
            transaction.savepoint_commit(savepoint)
            # 返回sku
            return sku

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM