Optimized API performance

This commit is contained in:
Jeremy Stretch
2016-08-22 15:16:49 -04:00
parent 76f0463290
commit f0a85b1dd3
11 changed files with 67 additions and 43 deletions

View File

@@ -1,21 +1,33 @@
from rest_framework import serializers
from extras.models import CF_TYPE_SELECT, CustomFieldChoice, Graph
from extras.models import CF_TYPE_SELECT, CustomFieldChoice, CustomFieldValue, Graph
class CustomFieldsSerializer(serializers.Serializer):
class CustomFieldSerializer(serializers.Serializer):
"""
Extends a ModelSerializer to render any CustomFields and their values associated with an object.
"""
custom_fields = serializers.SerializerMethodField()
def get_custom_fields(self, obj):
# Gather all CustomFields applicable to this object
fields = {cf.name: None for cf in self.context['view'].custom_fields}
# Attach any defined CustomFieldValues to their respective CustomFields
for cfv in obj.custom_field_values.all():
# Suppress database lookups for CustomFieldChoices. Instead, use the cached choice set from the view
# context.
if cfv.field.type == CF_TYPE_SELECT:
fields[cfv.field.name] = CustomFieldChoiceSerializer(instance=cfv.value).data
cfc = {
'id': int(cfv.serialized_value),
'value': self.context['view'].custom_field_choices[int(cfv.serialized_value)]
}
fields[cfv.field.name] = CustomFieldChoiceSerializer(instance=cfc).data
else:
fields[cfv.field.name] = cfv.value
return fields

View File

@@ -9,7 +9,7 @@ from django.shortcuts import get_object_or_404
from circuits.models import Provider
from dcim.models import Site, Device, Interface, InterfaceConnection
from extras.models import Graph, TopologyMap, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_PROVIDER, GRAPH_TYPE_SITE
from extras.models import CustomFieldChoice, Graph, TopologyMap, GRAPH_TYPE_INTERFACE, GRAPH_TYPE_PROVIDER, GRAPH_TYPE_SITE
from .serializers import GraphSerializer
@@ -22,7 +22,14 @@ class CustomFieldModelAPIView(object):
def __init__(self):
super(CustomFieldModelAPIView, self).__init__()
self.content_type = ContentType.objects.get_for_model(self.queryset.model)
self.custom_fields = self.content_type.custom_fields.all()
self.custom_fields = self.content_type.custom_fields.prefetch_related('choices')
# Cache all relevant CustomFieldChoices. This saves us from having to do a lookup per select field per object.
custom_field_choices = {}
for field in self.custom_fields:
for cfc in field.choices.all():
custom_field_choices[cfc.id] = cfc.value
self.custom_field_choices = custom_field_choices
class GraphListView(generics.ListAPIView):

View File

@@ -129,7 +129,8 @@ class CustomField(models.Model):
# Read date as YYYY-MM-DD
return date(*[int(n) for n in serialized_value.split('-')])
if self.type == CF_TYPE_SELECT:
return CustomFieldChoice.objects.get(pk=int(serialized_value))
# return CustomFieldChoice.objects.get(pk=int(serialized_value))
return self.choices.get(pk=int(serialized_value))
return serialized_value