from django.utils import timezone
from rest_framework import serializers, viewsets

from parkings.models import Parking, ParkingArea

from ..common import WGS84InBBoxFilter


class ParkingAreaStatisticsSerializer(serializers.ModelSerializer):
    current_parking_count = serializers.SerializerMethodField()

    def get_current_parking_count(self, area):
        count = Parking.objects.filter(
            parking_area=area,
            time_end__gte=timezone.now(),
            time_start__lte=timezone.now(),
        ).count()
        return self.blur_count(count)

    def blur_count(self, count):
        """
        Returns a blurred count, which is supposed to hide individual
        parkings.
        """
        if count <= 3:
            return 0
        else:
            return count

    class Meta:
        model = ParkingArea
        fields = (
            'id',
            'current_parking_count',
        )


class PublicAPIParkingAreaStatisticsViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = ParkingArea.objects.all()
    serializer_class = ParkingAreaStatisticsSerializer
    bbox_filter_field = 'areas'
    filter_backends = (WGS84InBBoxFilter,)
    bbox_filter_include_overlapping = True

from django.db.models import Case, Count, When
from django.utils import timezone
from rest_framework import serializers, viewsets

from parkings.models import ParkingArea

from ..common import WGS84InBBoxFilter


class ParkingAreaStatisticsSerializer(serializers.ModelSerializer):
    current_parking_count = serializers.SerializerMethodField()

    def get_current_parking_count(self, area):
        return self.blur_count(area['current_parking_count'])

    def blur_count(self, count):
        """
        Returns a blurred count, which is supposed to hide individual
        parkings.
        """
        if count <= 3:
            return 0
        else:
            return count

    class Meta:
        model = ParkingArea
        fields = (
            'id',
            'current_parking_count',
        )


class PublicAPIParkingAreaStatisticsViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = ParkingArea.objects.all()
    serializer_class = ParkingAreaStatisticsSerializer
    bbox_filter_field = 'areas'
    filter_backends = (WGS84InBBoxFilter,)
    bbox_filter_include_overlapping = True

    def get_queryset(self):
        now = timezone.now()

        return ParkingArea.objects.annotate(
            current_parking_count=Count(
                Case(
                    When(
                        parking__time_start__lte=now,
                        parking__time_end__gte=now,
                        then=1,
                    )
                )
            )
        ).values('id', 'current_parking_count')

Improve parking area statistics performance
Improve parking area statistics performance

+ from django.db.models import Case, Count, When
  from django.utils import timezone
  from rest_framework import serializers, viewsets
  
- from parkings.models import Parking, ParkingArea
+ from parkings.models import ParkingArea
  
  from ..common import WGS84InBBoxFilter
  
  
  class ParkingAreaStatisticsSerializer(serializers.ModelSerializer):
      current_parking_count = serializers.SerializerMethodField()
  
      def get_current_parking_count(self, area):
-         count = Parking.objects.filter(
-             parking_area=area,
-             time_end__gte=timezone.now(),
-             time_start__lte=timezone.now(),
-         ).count()
-         return self.blur_count(count)
+         return self.blur_count(area['current_parking_count'])
  
      def blur_count(self, count):
          """
          Returns a blurred count, which is supposed to hide individual
          parkings.
          """
          if count <= 3:
              return 0
          else:
              return count
  
      class Meta:
          model = ParkingArea
          fields = (
              'id',
              'current_parking_count',
          )
  
  
  class PublicAPIParkingAreaStatisticsViewSet(viewsets.ReadOnlyModelViewSet):
      queryset = ParkingArea.objects.all()
      serializer_class = ParkingAreaStatisticsSerializer
      bbox_filter_field = 'areas'
      filter_backends = (WGS84InBBoxFilter,)
      bbox_filter_include_overlapping = True
  
+     def get_queryset(self):
+         now = timezone.now()
+ 
+         return ParkingArea.objects.annotate(
+             current_parking_count=Count(
+                 Case(
+                     When(
+                         parking__time_start__lte=now,
+                         parking__time_end__gte=now,
+                         then=1,
+                     )
+                 )
+             )
+         ).values('id', 'current_parking_count')
+ 
Improve parking area statistics performance
## Code Before:
from django.utils import timezone
from rest_framework import serializers, viewsets

from parkings.models import Parking, ParkingArea

from ..common import WGS84InBBoxFilter


class ParkingAreaStatisticsSerializer(serializers.ModelSerializer):
    current_parking_count = serializers.SerializerMethodField()

    def get_current_parking_count(self, area):
        count = Parking.objects.filter(
            parking_area=area,
            time_end__gte=timezone.now(),
            time_start__lte=timezone.now(),
        ).count()
        return self.blur_count(count)

    def blur_count(self, count):
        """
        Returns a blurred count, which is supposed to hide individual
        parkings.
        """
        if count <= 3:
            return 0
        else:
            return count

    class Meta:
        model = ParkingArea
        fields = (
            'id',
            'current_parking_count',
        )


class PublicAPIParkingAreaStatisticsViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = ParkingArea.objects.all()
    serializer_class = ParkingAreaStatisticsSerializer
    bbox_filter_field = 'areas'
    filter_backends = (WGS84InBBoxFilter,)
    bbox_filter_include_overlapping = True

## Instruction:
Improve parking area statistics performance
## Code After:
from django.db.models import Case, Count, When
from django.utils import timezone
from rest_framework import serializers, viewsets

from parkings.models import ParkingArea

from ..common import WGS84InBBoxFilter


class ParkingAreaStatisticsSerializer(serializers.ModelSerializer):
    current_parking_count = serializers.SerializerMethodField()

    def get_current_parking_count(self, area):
        return self.blur_count(area['current_parking_count'])

    def blur_count(self, count):
        """
        Returns a blurred count, which is supposed to hide individual
        parkings.
        """
        if count <= 3:
            return 0
        else:
            return count

    class Meta:
        model = ParkingArea
        fields = (
            'id',
            'current_parking_count',
        )


class PublicAPIParkingAreaStatisticsViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = ParkingArea.objects.all()
    serializer_class = ParkingAreaStatisticsSerializer
    bbox_filter_field = 'areas'
    filter_backends = (WGS84InBBoxFilter,)
    bbox_filter_include_overlapping = True

    def get_queryset(self):
        now = timezone.now()

        return ParkingArea.objects.annotate(
            current_parking_count=Count(
                Case(
                    When(
                        parking__time_start__lte=now,
                        parking__time_end__gte=now,
                        then=1,
                    )
                )
            )
        ).values('id', 'current_parking_count')
