pan*_*ore 37 python django django-rest-framework
我正在为QuerySet中的每个项生成聚合:
def get_queryset(self):
from django.db.models import Count
queryset = Book.objects.annotate(Count('authors'))
return queryset
Run Code Online (Sandbox Code Playgroud)
但我没有得到JSON响应中的计数.
先感谢您.
Jos*_*iño 58
接受的解决方案将在返回结果时多次访问数据库.对于每个结果,count将对数据库进行查询.
问题是关于向序列化程序添加注释,这比count对响应中的每个项目执行查询更有效.
解决方案:
models.py
class Author(models.Model):
name = models.CharField(...)
other_stuff = models...
...
class Book(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(...)
publication_year = models...
...
Run Code Online (Sandbox Code Playgroud)
serializers.py
class BookSerializer(serializers.ModelSerializer):
authors = serializers.IntegerField()
class Meta:
model = Book
fields = ('id', 'title', 'authors')
Run Code Online (Sandbox Code Playgroud)
views.py
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.annotate(authors=Count('author'))
serializer_class = BookSerializer
...
Run Code Online (Sandbox Code Playgroud)
这将使数据库级别的计数,避免命中数据库以检索每个返回Book项目的作者计数.
Fiv*_*ver 25
从get_queryset返回的查询集提供了将通过序列化程序的事物列表,该序列化程序控制对象的表示方式.尝试在Book序列化程序中添加其他字段,例如:
author_count = serializers.IntegerField(
source='author_set.count',
read_only=True
)
Run Code Online (Sandbox Code Playgroud)
编辑:正如其他人所说的,这不是为返回许多结果的情况添加计数的最有效方法,因为它将为每个实例命中数据库.请查看@José的答案,以获得更有效的解决方案.
Fiver的解决方案将针对查询集中的每个实例访问数据库,因此如果您有一个大型查询集,他的解决方案将创建大量查询.
我会覆盖Book序列化程序的to_representation,它会重用注释的结果.它看起来像:
class BookSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
return {'id': instance.pk, 'num_authors': instance.authors__count}
class Meta:
model = Book
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
12855 次 |
| 最近记录: |