JeremyE
JeremyE

Reputation: 1418

Getting an Aggregate Value from a Many-to-Many Field inside a Serializer

We have an API endpoint that generates a response. However, we would like to aggregate some of the data and add an additional field to the serializer.

  {
        "id": 61,
        "not_owned_value": # This is what we're trying to get (Aggregate best_buy_price from not_owned_inventory PlayerProfiles)
        "not_owned_inventory": [ # PlayerProfile objects
            "29666196ed6900f07fc4f4af4738bffe",
            "0ff73ca20cd787c5b817aff62e7890da",
            "99d4eaef9991695d7ad94b83ad5c5223",
            "6fcabe9f9c8a95980923530e7d7353a7",
            "80b34c84a6e5ed25df112c11de676adc",
            "0a4c5b96474f0584519d1abc4364d5a2",
            "9ed1f55ac4f3b402b1d08b26870c34a6",
         ]
  }

Here is the models.py

class PlayerProfile(models.Model):
    card_id = models.CharField(max_length=120, unique=True, primary_key=True)
    name = models.CharField(max_length=120, null=True)

class PlayerListing(models.Model):
    player_profile = models.OneToOneField(
        PlayerProfile,
        on_delete=models.CASCADE,
        null=True)
    best_buy_price = models.IntegerField(null=True)

class InventoryLiveCollection(models.Model):
    not_owned_inventory = models.ManyToManyField(PlayerProfile, related_name="not_owned_inventory")

Here is the serializer.py

class InventoryLiveCollectionSerializer(serializers.ModelSerializer):
    not_owned_inventory = PlayerProfileAndListingForNesting(read_only=True, many=True)

    class Meta:
        model = InventoryLiveCollection
        fields = (
            'id',
            'date',
            'not_owned_value', # Trying to get this
            'not_owned_inventory',
        )

How can I aggregate the best_buy_price of the player_profile objects that belong to a specific InventoryLiveCollection__not_owned_inventory?

Upvotes: 1

Views: 337

Answers (1)

Arjun Shahi
Arjun Shahi

Reputation: 7330

You can try this.

 from django.db.models import Sum

 not_owned_value = serializers.SerializerMethodField()
    
 def get_not_owned_value(self, obj):
     value = obj.not_owned_inventory.all().aggregate(total=Sum('playerlisting__best_buy_price'))
     return value['total']

Upvotes: 1

Related Questions