DRF: Разделение данных между несколькими полями SerializerMethodFields в ListSerializer
У меня есть проект DRF со следующим представлением:
class AssetViewSet(
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet,
):
queryset = Asset.objects.all()
serializer_class = AssetSerializer
def get_serializer_class(self):
if self.action == "list":
return AssetListSerializer
if self.action == "retrieve":
return AssetSerializer
return AssetSerializer # For create/update/destroy
Моя проблема в AssetListSerializer:
class AssetListSerializer(serializers.ModelSerializer):
id = serializers.ReadOnlyField()
name = serializers.ReadOnlyField()
block_count = serializers.SerializerMethodField("get_block_count")
requirement_count = serializers.SerializerMethodField("get_requirement_count")
open_requirements = serializers.SerializerMethodField("get_open_requirements")
in_progress = serializers.SerializerMethodField("get_in_progress")
measure_count = serializers.SerializerMethodField("get_measure_count")
Все эти методы вызывают один и тот же внутренний (дорогой) метод, а затем работают с результатом:
def _get_asset_requirements(self, asset_id):
req = do_some_expensive_method(asset_id)
return req
def get_requirement_count(self, instance):
requirements = self._get_asset_requirements(instance.id)
blablabla
def get_open_requirements(self, instance):
requirements = self._get_asset_requirements(instance.id)
blablabla
def get_in_progress(self, instance):
requirements = self._get_asset_requirements(instance.id)
blablabla
Так что я хотел бы сделать только один раз для дорогого метода на объект и затем получить доступ к результату из SerializerMethodField-methods.
Я нашел эту часть в документации: https://www.django-rest-framework.org/api-guide/serializers/#customizing-listserializer-behavior
Однако я не знаю, как это реализовать. Моя идея была примерно такой:
@classmethod
def many_init(cls, *args, **kwargs):
cls.req = cls._get_asset_requirements(cls.instance.id)
return super().many_init(*args, **kwargs)
но это не работает, так как я не могу получить доступ к экземпляру таким образом, а документация здесь действительно неполная.
У кого-нибудь есть идея, как это решить?