Как объединить и агрегировать в Django REST Framework

Я совсем новичок в Django и в настоящее время застрял на следующей проблеме.

У меня есть такие модели как:

class City(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=100)
    area = models.FloatField()


class NoiseData(models.Model):
    location = models.CharField(max_length=100)
    city_id = models.ForeignKey(City,
                                on_delete=models.CASCADE)
    noise_type = models.CharField(max_length=30)

Я хотел бы иметь агрегацию данных по городам в моем api в форме, как:

[
        {
                "id": 1,
                "name": "New York",
                "count": 198, # this would be count of NoiseData,
                "count_area_normalized": 0.198 # this would be count of NoiseData / area of City,
                "noise_type_metadata": "{\"Loud Music/Party\": 167, \"Banging/Pounding\": 21, \"Loud Talking\": 9, \"Loud Television\": 1}", # ideally want a JSON in which I can show count for each noise_type in the city
           }

Заранее большое спасибо!

Для поля count и других, требующих вычислений, следует использовать SerializerMethodField.

from rest_framework import serializers
from django.db.models import Count

class CitySerializer(serializers.ModelSerializer):
    count = serializers.SerializerMethodField()
    count_area_normalized = serializers.SerializerMethodField()
    noise_type_metadata = serializers.SerializerMethodField()

    class Meta:
        model = City
        fields = ('name',)

    def get_count(self, obj):
        return NoiseData.objects.filrer(city_id=obj).count()

    def get_count_area_normalized(self, obj):
        return get_count(self, obj)/obj.area
   
    def get_noise_type_metadata(self,obj):
        return {data.noise_type:data.count for data in NoiseData.objects.filrer(city_id=obj).values('noise_type').annotate(count=Count('pk'))}

Это должно работать для вас, но для повышения производительности я бы вычислил все эти данные до того, как они окажутся в БД, используя ORM.

Вернуться на верх