Advanced Topics
Customization
Parameter names and wildcard values can be configured with the Django setting
REST_FLEX_FIELDS2. For the corresponding constants exposed by the package,
see API Reference.
Option |
Description |
Default |
|---|---|---|
|
Query parameter name for requested expansions. |
|
|
Maximum allowed expansion depth. |
|
|
Query parameter name for sparse field inclusion. |
|
|
Query parameter name for explicit exclusions. |
|
|
Whether recursive expansion patterns are allowed. |
|
|
Wildcard values that mean all fields or all expandable fields. Set to
|
|
Example:
REST_FLEX_FIELDS2 = {
"EXPAND_PARAM": "include",
}
Warning
Avoid direct import of the rest_flex_fields2 package in the Django settings.
Otherwise the configuration will not be picked up, because the variable does not
necessarily exist at the time of the import. Always reference package contents
like class names as strings, instead of importing them.
Defining Limits on Serializer Classes
You can set limits directly on a serializer class:
maximum_expansion_depthrecursive_expansion_permitted
Both settings raise serializers.ValidationError when violated. You can
customize the exceptions by overriding recursive_expansion_not_permitted()
and expansion_depth_exceeded().
Example:
from rest_flex_fields2.serializers import FlexFieldsModelSerializer
class PersonSerializer(FlexFieldsModelSerializer):
maximum_expansion_depth = 2
recursive_expansion_permitted = False
class Meta:
model = Person
fields = ["id", "name", "manager"]
expandable_fields = {
"manager": "people.api.serializers.PersonSerializer",
}
With this configuration, requests such as ?expand=manager.manager.manager
raise a validation error.
Serializer Introspection
Instances of FlexFieldsModelSerializer expose expanded_fields, which
records the fields expanded during serialization.
serializer = PersonSerializer(
instance=person,
context={"request": request},
)
payload = serializer.data
expanded = serializer.expanded_fields
expanded can be used in tests to assert behavior for a specific query.
Wildcards
You can use wildcard values such as * to expand or include all fields at a
given level.
Examples:
expand=*expand=menu.sectionsfields=*,restaurant.name,restaurant.address&expand=restaurant
Combining Sparse Fields and Expansion
Sparse fieldsets take precedence over expansion. If a field is not explicitly
allowed by fields, it will not be expanded even if it appears in expand.
For example, this request omits country from the response because fields
wins:
GET /person/13322?fields=id,name&expand=country
Response:
{
"id": 13322,
"name": "John Doe"
}
Utility Functions
For broader endpoint usage patterns that pair with these helpers, see Usage.
rest_flex_fields2.utils.is_expanded(request, field)
Returns whether a field was requested via the active expansion parameter.
rest_flex_fields2.utils.is_included(request, field)
Returns whether a field remains included after fields and omit are
applied.
Example view usage:
from rest_flex_fields2.utils import is_expanded
from rest_flex_fields.views import FlexFieldsModelViewSet
class PersonViewSet(FlexFieldsModelViewSet):
serializer_class = PersonSerializer
def get_queryset(self):
queryset = Person.objects.all()
if is_expanded(self.request, "country"):
queryset = queryset.select_related("country")
return queryset
Query Optimization Backend
FlexFieldsFilterBackend is an optional integration that applies queryset
optimization based on requested expansions and sparse fieldsets. You do not
need this backend to use dynamic expansion (expand) or sparse fieldsets
(fields and omit). Those core features work through the serializer
layer. But you can add FlexFieldsFilterBackend when you want automatic
queryset tuning from request parameters to reduce query count and payload
size automatically. It applies select_related(), prefetch_related(),
and only() based on the requested fields and expansions.
REST_FRAMEWORK = {
"DEFAULT_FILTER_BACKENDS": (
"rest_flex_fields2.filter_backends.FlexFieldsFilterBackend",
),
}
Warning
The optimization currently works for one nesting level only. Treat it as a convenience feature, not as a substitute for inspecting your queryset behavior.