簡體   English   中英

如何在 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM