Как использовать prefetch_related в django rest api с ключом foreying и наследием

Я работаю над проектом Django, он использует наследие и внешние ключи для своих моделей.

Вот эти модели:

class SetorFii(models.Model):
    name = models.CharField(max_length=255)

class Asset(models.Model):
    category = models.ForeignKey(
        Category, related_name='categories', on_delete=models.CASCADE)
    ticker = models.CharField(max_length=255, unique=True)
    price = models.FloatField()

class Fii(Asset):
    setor_fii = models.ForeignKey(
        SetorFii, null=True, default=None, on_delete=models.CASCADE, related_name="setor_fiis")

Class Crypto(Asset):
    circulating_supply = models.FloatField(default=0) 


class PortfolioAsset(models.Model):
    asset = models.ForeignKey(Asset, on_delete=models.CASCADE)


Я хотел бы получить поле setor_fii в PortfolioAssetSerializer, Это то, что я пробовал без успеха.

Я получаю это сообщение об ошибке: Cannot find 'setor_fii' on PortfolioAsset object, 'setor_fii' is an invalid parameter to prefetch_related()

Хотелось бы получить некоторую помощь для достижения этой цели.

Сериализатор:

class PortfolioAssetSerializer(serializers.ModelSerializer):
    category = serializers.CharField(source='asset.category.name')
    setor_fii = serializers.CharField(source='asset.setor_fii')

    class Meta:
        model = models.PortfolioAsset
        fields = (
            'id',
            'category',
            'setor_fii'
        )

Вид


class PortfolioAssetList(generics.ListAPIView):
    serializer_class = serializers.PortfolioAssetSerializer

    def get_queryset(self):
        return models.PortfolioAsset.objects.filter(portfolio_id=self.kwargs['pk']).prefetch_related('setor_fii')


Чтобы получить префетч setor_fii, вам придется пройти через asset. Поскольку Fii наследует от Asset, Asset будет иметь автоматически созданное поле один-к-одному с именем fii. Затем вы можете использовать его для доступа к setor_fii:

PortfolioAsset.objects.filter(
    portfolio_id=self.kwargs['pk'],
).prefetch_related(
    'asset__fii__setor_fii',
)

Кроме того, поскольку все отношения здесь только один к одному, вы можете использовать select_related вместо prefetch_related, чтобы получить их все за один запрос (по сравнению с тремя запросами с использованием prefetch_related):

PortfolioAsset.objects.filter(
    portfolio_id=self.kwargs['pk'],
).select_related(
    'asset__fii__setor_fii',
)
Вернуться на верх