Automatic QuerySet optimization
Allowing your end-users to vary the API response is a very powerful feature, but can result in extremely numerous / expensive database queries being made, depending on what is being expanded.
Luckily, extensions provides the ability to automatically optimize your
queryset, such that the appropriate
.select_related()
and
.prefetch_related()
calls are made as required.
Activating
Automatic queryset optimization is an experimental feature, and is not applied by default.
Per-view
You can enable the feature for an individual view by setting the
extensions_auto_optimize
class attribute:
# views.py
class APIView(SerializerExtensionsAPIViewMixin, GenericAPIView):
queryset = ...
extensions_auto_optimize = True
The get_extensions_auto_optimize()
method can also be used to achieve the
same result.
Globally
Alternatively, you can enable the feature for all views through the
AUTO_OPTIMIZE
setting:
# settings.py
REST_FRAMEWORK = dict(
SERIALIZER_EXTENSIONS=dict(
AUTO_OPTIMIZE=True
)
)
Configuration
Optimizations for model to model serializer relationships are calculated automatically. In other cases, a list of related names to select/prefetch can be set explicitly against the field definition, and will be applied when the field is expanded.
class Serializer(SerializerExtensionsMixin, ModelSerializer):
class Meta:
expandable_fields = dict(
non_model=dict(
serializer=NonModelSerializer,
select_related=['related_name'],
prefetch_related=['related_name'],
)
)
In situations where automatic field optimization either fails or is unwanted, the field definition can also be used to disable the feature:
class Serializer(SerializerExtensionsMixin, ModelSerializer):
class Meta:
expandable_fields = dict(
child=dict(
serializer=ChildSerializer,
auto_optimize=False,
)
)