我是第一次使用 DRF。我一直在阅读文档页面,但不知道如何执行此操作。
我有两个模型,AdPrice 模型引用广告模型。我需要列出广告的各种价格。
我的问题是:如何获得这样的广告列表?
[
{
"title": "Some long title for Ad1",
"name": "Name Ad1",
"prices": {
{ "name": "price now", "price": 200 },
{ "name": "price later", "price": 300 }
}
},
]
模型.py
class Ad(models.Model):
title = models.CharField(max_length=250)
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class AdPrice(models.Model):
ad = models.ForeignKey(Ad)
name = models.CharField(max_length=50)
price = models.DecimalField(max_digits=6, decimal_places=2)
def __str__(self):
return self.name
序列化器.py
class AdPriceSerializer(serializers.Serializer):
name = serializers.CharField(max_length=50)
price = serializers.DecimalField(max_digits=6, decimal_places=2)
class Meta:
model = AdPrice
class AdSerializer(serializers.Serializer):
title = serializers.CharField(max_length=250)
name = serializers.CharField(max_length=100)
prices = AdPriceSerializer(many=True)
View .py
class AdViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = Ad.objects.all().order_by('-date_inserted')
serializer_class = AdSerializer
当我尝试上面的代码时,出现此错误:
AttributeError at /ads/
Got AttributeError when attempting to get a value for field `prices` on serializer `AdSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Ad` instance.
Original exception text was: 'Ad' object has no attribute 'prices'.
有什么线索可以解决这个问题吗?
最诚挚的问候, 安德烈·洛佩斯。
最佳答案
从我在这里看到的,您缺少
中的read_only=True
和 class meta
class AdSerializer(serializers.Serializer):
title = serializers.CharField(max_length=250)
name = serializers.CharField(max_length=100)
prices = AdPriceSerializer(many=True, read_only=True)
class Meta:
model = Ad
并且为了避免 n+1 查询问题,您需要将 queryset
重写为
从 django.db.models 导入预取
queryset=Ad.objects.all().order_by('-date_inserted').prefetch_related(Prefetch('adprice_set', queryset=AdPrice.objects.filter(ad_id__in=queryset), to_attr='prices'))
由于 Django 有一个惰性 ORM,这意味着对于其中的每个广告,它都会进行另一个查询来获取 AdPrices。因此,对于 100 个广告,它将进行 200 次查询。这不是最有效的解决方案,对吧?通过预取,您只需进行两次查询即可,一次查询获取所有广告
,另一个查询获取所有相关的adprices
。
关于Django-Rest-Framework - 嵌套对象和序列化器,如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46207998/