[英]How to order queryset based on best match in django-rest-framework?
[英]how to add annotate data in django-rest-framework queryset responses?
我正在為 QuerySet 中的每個項目生成聚合:
def get_queryset(self):
from django.db.models import Count
queryset = Book.objects.annotate(Count('authors'))
return queryset
但我沒有得到 JSON 響應中的計數。
先感謝您。
接受的解決方案將在返回結果時多次訪問數據庫。 對於每個結果,將對數據庫進行count
查詢。
問題是向序列化程序添加注釋,這比對響應中的每個項目進行count
查詢更有效。
一個解決方案:
模型.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...
...
序列化程序.py
class BookSerializer(serializers.ModelSerializer):
authors = serializers.IntegerField()
class Meta:
model = Book
fields = ('id', 'title', 'authors')
視圖.py
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.annotate(authors=Count('author'))
serializer_class = BookSerializer
...
這將在數據庫級別進行計數,避免訪問數據庫以檢索每個返回的Book
項目的作者計數。
從 get_queryset 返回的查詢集提供將通過序列化程序的事物列表,序列化程序控制對象的表示方式。 嘗試在您的 Book 序列化程序中添加一個附加字段,例如:
author_count = serializers.IntegerField(
source='author_set.count',
read_only=True
)
編輯:正如其他人所說,這不是為返回許多結果的情況添加計數的最有效方法,因為它會為每個實例訪問數據庫。 有關更有效的解決方案,請參閱 @José 的答案。
Fiver 的解決方案將針對查詢集中的每個實例命中數據庫,因此如果您有一個大型查詢集,他的解決方案將創建大量查詢。
我會覆蓋你的 Book 序列化程序的to_representation ,它重用annotation的結果。 它看起來像:
class BookSerializer(serializers.ModelSerializer):
def to_representation(self, instance):
return {'id': instance.pk, 'num_authors': instance.authors__count}
class Meta:
model = Book
所以,如果你做這樣的注釋
Model.objects.annotate(
some_new_col=Case(
When(some_field=some_value, then=Value(something)),
# etc...
default=Value(something_default),
output_field=SomeTypeOfField(),
)
).filter()#etccc
並且解釋器拋出一個錯誤,即something
不是相關serializer
的模型字段,有一個解決方法。 這不是很好,但是如果您添加一個方法some_new_col
,它會識別來自上面查詢的值。 以下將做得很好。
def some_new_col(self):
pass;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.