我第一次使用DRF。我一直在阅读文档页面,但不知道如何做到这一点。
我有两个模型,AdPrice模型引用广告模型。我需要列出广告的各种价格。
我的问题是:我怎样才能获得这样的广告列表?
[
{
"title": "Some long title for Ad1",
"name": "Name Ad1",
"prices": {
{ "name": "price now", "price": 200 },
{ "name": "price later", "price": 300 }
}
},
]
models.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
serializers.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)
views.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'.
关于如何解决这个问题的任何线索?
最诚挚的问候, 安德烈·洛佩斯。
答案 0 :(得分:2)
从我在这里看到的内容,你错过了
中的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
from django.db.models import Prefetch
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次查询。不是最有效的解决方案,对吗?通过预取,您只需将两个查询缩短,一个用于获取所有ads
,另一个用于获取所有相关adprices
。