Как использовать 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',
)