Django Rest框架-嵌套对象和序列化程序,如何实现?
我第一次使用DRF。我一直在阅读文档页面,但没有关于如何做到这一点的线索 我有两个模型,AdPrice模型参考Ad模型。我需要列出广告的各种价格 我的问题是:我怎样才能得到这样的广告列表Django Rest框架-嵌套对象和序列化程序,如何实现?,django,django-rest-framework,Django,Django Rest Framework,我第一次使用DRF。我一直在阅读文档页面,但没有关于如何做到这一点的线索 我有两个模型,AdPrice模型参考Ad模型。我需要列出广告的各种价格 我的问题是:我怎样才能得到这样的广告列表 [ { "title": "Some long title for Ad1", "name": "Name Ad1", "prices": { { "name": "price now", "price": 200 },
[
{
"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
序列化程序.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'.
关于如何解决这个问题有什么线索吗
致以最良好的祝愿,
安德烈·洛佩斯。从我在这里看到的情况来看,您缺少
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,这意味着对于你在那里的每一个广告,它都会进行另一个查询来获取Adprice。因此,对于100个广告,它将发出200个查询。不是最有效的解决方案,对吧?。使用prefetch,您只需要两个查询,一个查询获取所有的
广告,另一个查询获取所有相关的价格您是否在AdSerializer
上定义了meta类?嗨,Borko Kovacev。谢谢,你的代码成功了。这段代码的问题是queryset,我更习惯SQL。是否可以使用RawQuery获得相同的结果?非常感谢。@André嘿,Andre!当然queryset=Ad.objects.raw(此处包含原始SQL)
将此问题作为参考-