Home > Enterprise >  Django Rest - retrive data from nested class
Django Rest - retrive data from nested class

Time:11-25

In my following output (below), I would like to get the value from rating field. As you can see there are two rates for that car model. The value from rating will be needed to calculate average rate for that model.

{
    "id": 4,
    "make": "Citroen",
    "model": "C4",
    "rates": [
        {
            "id": 6,
            "rating": 4,
            "car_id": 4
        },
        {
            "id": 7,
            "rating": 4,
            "car_id": 4
        }
    ],
    "avg_rating": 0.0
}

Here is my models.py:

class Car(models.Model):
    make = models.CharField(max_length=15)
    model = models.CharField(max_length=15)
    avg_rating = models.FloatField(default=0)

    def __str__(self):      # print it when Car instance is needed
        return self.make


class CarRate(models.Model):
    car_id = models.ForeignKey(Car, related_name='rates',
                            on_delete=models.CASCADE,
                            default=0)
    rating = models.PositiveIntegerField(default=0)

My serializers.py:

class CarRateSerializer(serializers.ModelSerializer):
    class Meta:
        model = CarRate
        fields=('__all__')
    


class CarSerializer(serializers.ModelSerializer):
    rates = CarRateSerializer(many=True, read_only=True)

    def create(self, validated_data):
        rates_data = validated_data.pop("rates")
        car = Car.objects.create(**validated_data)
        for rate_data in rates_data:
            CarRate.objects.create(car=car, **rate_data)
        return car

    class Meta:
        model = Car
        fields = ('id', 'make', 'model','rates','avg_rating')

I have no idea how to retrive those data.

Later in views.py while doing GET I tried to many things, i.e.

my_data=getattr(cars, 'rates["rating"]')

Like I would try to get a dict value, it didn't work.

CodePudding user response:

Are you encountering an error?

Have you tried to write the serialisers for these models?

Look here: https://www.django-rest-framework.org/tutorial/1-serialization/#using-modelserializers

CodePudding user response:

One option would be to create a SerializerMethodField for avg_rating in CarSerializer.

Something like this:

class CarSerializer(serializers.ModelSerializer):
    rates = CarRateSerializer(many=True, read_only=True)
    avg_rating = serializers.SerializerMethodField()

    class Meta:
        model = Car
        fields = ('id', 'make', 'model','rates','avg_rating')

    def get_avg_rating(self, obj):
        // obj will hold your current Car object
        // Code for finding the CarRate objects using the Car obj
        // Average calculation - avg_rating = total_rating/no_of_ratings
        return avg_rating
  • Related