I am working on this Django project, it uses heritage and foreign keys for its models.
These are the models:
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)
I would like to get the field setor_fii
in the PortfolioAssetSerializer
, That is what I tried without success.
I get this error message: Cannot find 'setor_fii' on PortfolioAsset object, 'setor_fii' is an invalid parameter to prefetch_related()
Would like some help to achieve that.
The serializer:
class PortfolioAssetSerializer(serializers.ModelSerializer):
category = serializers.CharField(source='asset.category.name')
setor_fii = serializers.CharField(source='asset.setor_fii.name')
class Meta:
model = models.PortfolioAsset
fields = (
'id',
'category',
'setor_fii'
)
The view
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')
CodePudding user response:
To prefetch setor_fii
, you will have to go through asset
. Since Fii
inherits from Asset
, Asset
will have an automatically created one-to-one field named fii
. You can then use that to access setor_fii
:
PortfolioAsset.objects.filter(
portfolio_id=self.kwargs['pk'],
).prefetch_related(
'asset__fii__setor_fii',
)
Also since the whole relationships here are just one to ones, you can use select_related
instead of prefetch_related
to get them all in one query (compared to three queries using prefetch_related
):
PortfolioAsset.objects.filter(
portfolio_id=self.kwargs['pk'],
).select_related(
'asset__fii__setor_fii',
)