如何在 django rest api 中使用 prefetch_related 和 foreying key 和 heritage

How to use prefetch_related in django rest api with foreying key and heritage

我正在处理这个 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)

我想获取PortfolioAssetSerializer中的字段setor_fii,这是我试过没有成功。

我收到此错误消息: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.name')

    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 继承自 AssetAsset 将自动创建一个名为 fii 的 one-to-one 字段。然后您可以使用它来访问 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',
)