Django Rest框架-嵌套对象和序列化程序,如何实现?

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 },

我第一次使用DRF。我一直在阅读文档页面,但没有关于如何做到这一点的线索

我有两个模型,AdPrice模型参考Ad模型。我需要列出广告的各种价格

我的问题是:我怎样才能得到这样的广告列表

[
    {
    "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)
将此问题作为参考-