Skip to content

Commit

Permalink
perf: instance cache and select-related for license serialization
Browse files Browse the repository at this point in the history
  • Loading branch information
iloveagent57 committed Feb 21, 2024
1 parent 688d048 commit f7a0ff0
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
15 changes: 15 additions & 0 deletions license_manager/apps/api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.core.validators import MinLengthValidator
from django.utils.functional import cached_property
from rest_framework import serializers
from rest_framework.fields import SerializerMethodField

Expand Down Expand Up @@ -106,6 +107,7 @@ class MinimalCustomerAgreementSerializer(serializers.ModelSerializer):
Minimal serializer for the `CustomerAgreement` model that does not
include information about related subscription plan records.
"""
net_days_until_expiration = serializers.SerializerMethodField()

class Meta:
model = CustomerAgreement
Expand All @@ -118,6 +120,19 @@ class Meta:
'net_days_until_expiration',
]

def get_net_days_until_expiration(self, obj):
"""
Cache the net_days_until_expiration of the agreement
to serializer for the lifetime of this serializer instance.
"""
# pylint: disable=attribute-defined-outside-init
if hasattr(self, '_cached_net_days_until_expiration'):
return self._cached_net_days_until_expiration

value = obj.net_days_until_expiration
self._cached_net_days_until_expiration = value
return value


class CustomerAgreementSerializer(serializers.ModelSerializer):
"""
Expand Down
20 changes: 18 additions & 2 deletions license_manager/apps/api/v1/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,9 @@ def base_queryset(self):
return License.objects.filter(
subscription_plan=self._get_subscription_plan(),
user_email=self.request.user.email,
).select_related(
'subscription_plan',
'subscription_plan__customer_agreement',
).exclude(
status=constants.REVOKED
).order_by('status', '-subscription_plan__expiration_date')
Expand All @@ -562,14 +565,22 @@ def _get_subscription_plan(self):
"""
Helper that returns the subscription plan specified by `subscription_uuid` in the request.
"""
# pylint: disable=attribute-defined-outside-init
if hasattr(self, '_cached_subscription_plan'):
return self._cached_subscription_plan

subscription_uuid = self.kwargs.get('subscription_uuid')
if not subscription_uuid:
return None

value = None
try:
return SubscriptionPlan.objects.get(uuid=subscription_uuid)
value = SubscriptionPlan.objects.get(uuid=subscription_uuid)
except SubscriptionPlan.DoesNotExist:
return None
pass

self._cached_subscription_plan = value
return value


class LicenseAdminViewSet(BaseLicenseViewSet):
Expand Down Expand Up @@ -640,6 +651,11 @@ def base_queryset(self):
"""
queryset = License.objects.filter(
subscription_plan=self._get_subscription_plan()
).select_related(
'subscription_plan',
'subscription_plan__customer_agreement',
).prefetch_related(
'subscription_plan__renewal',
).order_by(
'status', 'user_email'
)
Expand Down
2 changes: 1 addition & 1 deletion license_manager/apps/subscriptions/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class CustomerAgreement(TimeStampedModel):

history = HistoricalRecords()

@property
@cached_property
def net_days_until_expiration(self):
"""
Returns the max number of days until expiration
Expand Down

0 comments on commit f7a0ff0

Please sign in to comment.