我產生聚集在一個QuerySet每個項目:如何在django-rest-framework的queryset響應中添加註釋數據?
def get_queryset(self):
from django.db.models import Count
queryset = Book.objects.annotate(Count('authors'))
return queryset
但我沒有得到的JSON響應計數。
謝謝你提前。
我產生聚集在一個QuerySet每個項目:如何在django-rest-framework的queryset響應中添加註釋數據?
def get_queryset(self):
from django.db.models import Count
queryset = Book.objects.annotate(Count('authors'))
return queryset
但我沒有得到的JSON響應計數。
謝謝你提前。
從get_queryset返回的查詢集提供了將通過序列化程序的事件列表,該序列化程序控制着對象如何表示。嘗試在你的書串行器增加一個額外的領域,如:
author_count = serializers.IntegerField(
source='author_set.count',
read_only=True
)
晚五的解決方案將達到分貝爲每個實例的查詢集,所以如果你有一個大的查詢集,他的解決方案將創造大量的查詢。
我會重寫to_representation您的圖書串行的,它重新使用註釋結果。它看起來像這樣:
class BookSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
return {'id': instance.pk, 'num_authors': instance.authors__count}
class Meta:
model = Book
接受的解決方案將返回結果數次的數據庫。對於每個結果,將會對數據庫執行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...
...
serializers.py
class BookSerializer(serializers.ModelSerializer):
authors = serializer.IntegerField()
class Meta:
model = Book
fields = ('id', 'title', 'authors')
views.py
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.annotate(authors=Count('author'))
serializer_class = BookSerializer
...
這將使在數據庫中的計數級別,避免t o點擊數據庫檢索返回的Book
項目中的每一個的作者數。
您可否詳細說明一下如何使用BookViewSet類創建?我試圖達到相同的結果,但一旦我有ViewSet,我不知道如何使用它。 –
它應該是被接受的答案。 – jrobichaud
你能否解釋一下 - 爲什麼Fiver的解決方案會產生很多查詢?我認爲序列化程序字段將在queryset執行後進行處理,這將執行正確的連接/分組? – DmitrySemenov
我用'Field(source ='annotated_field')製作了它' – outoftime
@DmitrySemenov我認爲source參數會引用一個方法而不是變量。我之前在代碼中有「source ='author_set.count'」,但事實證明生成了很多查詢(你可以從調試器中看到它),大多數查詢都重複了,並且調用了count方法。 – Tobias