簡體   English   中英

DRF在序列化器中使用其他與模型相關的字段

[英]DRF use another model related fields in serializer

我有3個型號產品 - Peyment - ProductDiscountControll

PeymentProductDiscountControll產品表中的“ product ”列相關

我想有這樣的相關ProductDiscountControll數據discountdiscount_code_precent在GET請求peyment serilizer。

為了做到這一點,我嘗試在我的Serializer類中遵循以下代碼

def get_product_discount(self, obj):
    return obj.product.product_discount.discount

但是服務器說:

Field name `product_discount` is not valid for model `Peyment`.

我也嘗試過這種方式:

product_discount = ProductDiscountControllSerializer(many=True,read_only=True)

但是product_discount在結果中不可用

我的看法是這樣的

class PeymentAPIView(APIView, mixins.DestroyModelMixin):
    permission_classes = [IsSafeGuard]

    def get(self, request):
        pay = Peyment.objects.filter(
            email=request.user.email,
            status=0,

        )
        serializer = PeymentSerializer(instance=pay, many=True)
        return Response(serializer.data)

這與獲取請求的相關Serializer類有關:

class PeymentSerializer(ModelSerializer):
    producttitle = serializers.SerializerMethodField()

    def get_producttitle(self, obj):
        return obj.product.title

    productprice = serializers.SerializerMethodField()

    def get_productprice(self, obj):
        return obj.product.price


    def get_discount(self, obj):
        return obj.product_discount.discount
    #product_discount = ProductDiscountControllSerializer(many=True,read_only=True)


    class Meta:
        model = Peyment
        fields = [
            'product',
            'id',
            'producttitle',
            'productprice',
            'discount',
            'status',
            'user',
            'email',
            'transfer_id',
            'created_date',
            'updated_date',
        ]
        read_only_fields = ['email', 'user', 'producttitle', 'productprice']

這是產品型號:

class Product(models.Model):
    product_id = models.AutoField(primary_key=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, db_index=True)
    title = models.CharField(max_length=200)
    video_length = models.CharField(max_length=20, null=True, blank=True)
    mini_description = models.CharField(max_length=1000, null=True, blank=True)
    full_description = models.TextField(null=True, blank=True)
    you_need = models.CharField(max_length=1000, null=True)
    you_learn = models.CharField(max_length=2000, null=True)
    price = models.CharField(max_length=50, null=True, blank=True)
    video_level = models.CharField(max_length=100, null=True, blank=True)
    created_date = models.DateTimeField(auto_now_add=True)
    updated_date = models.DateTimeField(auto_now=True)
    image = models.FileField(upload_to=upload_to_custom_p,null=True,blank=True)

付款方式:

class Peyment(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, to_field='product_id',
                                related_name='product_peyment')
    status = models.CharField(max_length=30, null=True)
    user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
    transfer_id = models.CharField(max_length=100, null=True, blank=True)
    email = models.EmailField()
    created_date = models.DateTimeField(auto_now_add=True)
    updated_date = models.DateTimeField(auto_now=True)

和折扣模式:

class ProductDiscountControll(models.Model):
    product = models.OneToOneField(Product, on_delete=models.CASCADE, to_field='product_id',
                                related_name='product_discount')
    discount = models.IntegerField(max_length=50, null=True, blank=True)
    discount_code = models.CharField(max_length=50, null=True, blank=True)
    discount_code_precent = models.CharField(max_length=80, null=True, blank=True)
    updated_date = models.DateTimeField(auto_now=True)

更新 :

# product peyment
class PeymentSerializer(ModelSerializer):
    producttitle = serializers.SerializerMethodField()

    def get_producttitle(self, obj):
        return obj.product.title

    productprice = serializers.SerializerMethodField()

    def get_productprice(self, obj):
        return obj.product.price

    def get_discount(self, obj):
        serializer = ProductDiscountControllSerializer(obj.product.product_discount)
        return serializer.data


    class Meta:
        model = Peyment
        fields = [
            'product',
            'id',
            'producttitle',
            'productprice',
            'discount',
            'status',
            'user',
            'email',
            'transfer_id',
            'created_date',
            'updated_date',
        ]
        read_only_fields = ['email', 'user', 'producttitle', 'productprice']

您只能在序列化器的方法中使用product.product_discount字段名稱。 要返回序列化的數據,您應該將此值傳遞給ProductDiscountControllSerializer並返回serializer.data

def get_discount(self, obj):
    discount = getattr(obj.product, 'product_discount', None)
    if discount: 
        serializer = ProductDiscountControllSerializer(discount)
        return serializer.data 
    return None

UPD

您應該在SerializerMethodField中使用SerializerMethodField顯式聲明discount字段,以在fileds列表中使用它:

class PeymentSerializer(ModelSerializer):
    discount = serializers.SerializerMethodField()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM