Home > other >  How to compare two serializer field and show whichever is higher in django rest
How to compare two serializer field and show whichever is higher in django rest

Time:11-22

I have product serializer which return category_offer_price & product_offer_price, before getting this response I want to compare both price and only return whichever is highest price.

#Serilaizer.py

class ProductSerializer(ModelSerializer):
    category = CategorySerializer()
    product_offer_price = SerializerMethodField()
    category_offer_price = SerializerMethodField()

    class Meta:
        model = Products
        fields = [
            "id",
            "product_name",
            "slug",
            "category",
            "description",
            "category_offer_price",
            "product_offer_price",
            "base_price",
            "stock",
            "is_available",
            "created_date",
            "images",
            "images_two",
            "images_three",
        ]

    def get_product_offer_price(self, obj):
        try:
            product_offer = ProductOffer.objects.get(product=obj)
            if product_offer.is_active:
                offer_price = product_offer.product_offer_price()
                return offer_price
        except Exception:
            pass
        return None

    def get_category_offer_price(self, obj):
        try:
            category_offer = CategoryOffer.objects.get(category=obj.category)
            if category_offer.is_active:
                offer_price = category_offer.category_offer_price(obj)
                return offer_price
        except Exception:
            pass
        return None

#Models.py

class Products(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    product_name = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(max_length=100, unique=True)
    description = models.TextField(max_length=500)
    base_price = models.IntegerField()
    images = models.ImageField(upload_to="photos/products")
    images_two = models.ImageField(upload_to="photos/products")
    images_three = models.ImageField(upload_to="photos/products")
    stock = models.IntegerField()
    is_available = models.BooleanField(default=True)
    created_date = models.DateTimeField(auto_now_add=True)
    modified_date = models.DateTimeField(auto_now=True)

    class Meta:
        verbose_name_plural = "Products"

    def __str__(self):
        return self.product_name

I'd like to know is it possible to compare serializer fields in a serializer class?

CodePudding user response:

You can override to_representation()

Example:

class ProductSerializer(ModelSerializer):
    category = CategorySerializer()
    product_offer_price = SerializerMethodField()
    category_offer_price = SerializerMethodField()

    ...

    ...
    def to_representation(self, instance):
        data = super().to_representation(instance)
        # access required fields like this
        product_offer_price = data['product_offer_price']
        category_offer_price = data['category_offer_price']

        # do calculations here and returning the desired field as `calculated_price`
        if category_offer_price > product_offer_price:
            data['calculated_price'] = category_offer_price
        else:
            data['calculated_price'] = product_offer_price
        return data

CodePudding user response:

You can move into one method, to validate your field. Also, substitute your try:except with get-object-or-404 method and your serializer fields with all value since you are using everything, to have a much cleaner code.

from django.shortcuts import get_object_or_404

class ProductSerializer(ModelSerializer):
    category = CategorySerializer()
    price = SerializerMethodField()

    class Meta:
        model = Products
        fields = '__all__'

    def get_price(self, obj):
        product_offer = get_object_or_404(ProductOffer, product=obj)
        category_offer = get_object_or_404(CategoryOffer, category=obj.category)

        if product_offer.is_active and category_offer.is_active:
            if product_offer.product_offer_price() > category_offer.category_offer_price(obj):
                    return product_offer.product_offer_price()
            else:
                    return category_offer.category_offer_price(obj)

        elif product_offer.is_active and not category_offer.is_active:
            return product_offer.product_offer_price()

        elif category_offer.is_active and not product_offer.is_active:
            return category_offer.category_offer_price(obj)

EDIT: As you can see I used the classic if/else in this solution, although since Python 3.10 you can use the Match case statement to substitute these conditions chain.

  • Related