diff --git a/src/dso_api/dynamic_api/serializers/factories.py b/src/dso_api/dynamic_api/serializers/factories.py index 7f42d0738..e04e51443 100644 --- a/src/dso_api/dynamic_api/serializers/factories.py +++ b/src/dso_api/dynamic_api/serializers/factories.py @@ -534,11 +534,9 @@ def _build_serializer_embedded_field( embedded_field = EmbeddedFieldClass( serializer_class=cast(type[base.DynamicSerializer], serializer_class), - # serializer_class=serializer_class, + field_schema=field_schema, source=model_field.name, ) - # Attach the field schema so access rules can be applied here. - embedded_field.field_schema = field_schema # The field name is still generated from the model_field, in case this is a reverse field. serializer_part.add_embedded_field(toCamelCase(model_field.name), embedded_field) diff --git a/src/dso_api/dynamic_api/serializers/fields.py b/src/dso_api/dynamic_api/serializers/fields.py index 2967173b0..d26f87be7 100644 --- a/src/dso_api/dynamic_api/serializers/fields.py +++ b/src/dso_api/dynamic_api/serializers/fields.py @@ -63,8 +63,18 @@ def __init__(self, table_schema: DatasetTableSchema, *args, **kwargs): # Init adds temporal definitions at construction, removing runtime model lookups. # It also allows the PK optimization to be used. super().__init__(*args, **kwargs) + + # Link the table to perform temporal query filtering self.table_schema = table_schema + def __deepcopy__(self, memo): + # Fix a massive performance hit when DRF performs a deepcopy() of all fields + result = self.__class__.__new__(self.__class__) + memo[id(result)] = self + result.__dict__.update({k: v for k, v in self.__dict__.items() if k != "table_schema"}) + result.table_schema = self.table_schema + return result + def use_pk_only_optimization(self): return True # only need to have an "id" here. diff --git a/src/rest_framework_dso/fields.py b/src/rest_framework_dso/fields.py index 2151019ed..6fe4efb29 100644 --- a/src/rest_framework_dso/fields.py +++ b/src/rest_framework_dso/fields.py @@ -15,6 +15,7 @@ from rest_framework.exceptions import ValidationError from rest_framework_gis.fields import GeometryField from schematools.contrib.django.models import LooseRelationField +from schematools.types import DatasetFieldSchema from rest_framework_dso.utils import group_dotted_names, unlazy_object @@ -289,14 +290,24 @@ def __init__( self, serializer_class: type[serializers.Serializer], *, + field_schema: DatasetFieldSchema | None = None, source=None, ): self.serializer_class = serializer_class self.source = source self.field_name = None + self.field_schema = field_schema self.parent_serializer_class = None + def __deepcopy__(self, memo): + # Fix a massive performance hit when DRF performs a deepcopy() of all fields + result = self.__class__.__new__(self.__class__) + memo[id(result)] = self + result.__dict__.update({k: v for k, v in self.__dict__.items() if k != "field_schema"}) + result.field_schema = self.field_schema + return result + def __repr__(self): try: parent_serializer = self.parent_serializer_class.__name__