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)

но это не работает, так как я не могу получить доступ к экземпляру таким образом, а документация здесь действительно неполная.

У кого-нибудь есть идея, как это решить?

Вернуться на верх