Django-Rest-Framework - 嵌套对象和序列化器,如何?

标签 django django-rest-framework

我是第一次使用 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=Trueclass 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/

相关文章:

django - Django 1.6.2 中的 HTTP_HOST header 无效

javascript - Greasemonkey POST 请求总是返回 400 错误

django - Django REST Framework 故意引发错误时的事务错误

python - 如何修复 Django REST Framework 中的 UnicodeDecodeError?

python - DRF - 向可浏览的 api 发送额外数据

python - Django 迁移没有迁移 authtoken 和 session

python - 如何将 Django Rest Framework 与 contrib.auth View 连接

python - django 模板中的字典查找

python - Django 反向 url 找到参数但失败关键字

python - Tango with Django (v1.9/1.10) - 第 5 章,populate_rango 问题