2013-08-25 25 views

答えて

18

get_querysetから返されたクエリーセットは、シリアライザを経由してオブジェクトの表現方法を制御するもののリストを提供します。以下のように、あなたのブックシリアライザに追加フィールドを追加してみてください:あなたが大規模なクエリセットを持っている場合は、彼の解決策は、クエリの多くを作成しますので、

author_count = serializers.IntegerField(
    source='author_set.count', 
    read_only=True 
) 
6

ドル紙幣のソリューションは、クエリセット内のすべてのインスタンスのDBをヒットします。

私はto_representationごブック・シリアライザのを上書きするだろう、それは注釈からの結果を再利用します。

class BookSerializer(serializers.ModelSerializer): 
    def to_representation(self, instance): 
     return {'id': instance.pk, 'num_authors': instance.authors__count} 

    class Meta: 
     model = Book 
+5

plsは説明できますか?Fiverのソリューションが多くのクエリを生成する理由を教えてください。 querysetが実行された後、シリアライザフィールドが処理されると思っていました。これは適切な結合/グループ化を行いますか? – DmitrySemenov

+0

私は 'Field(source = 'annotated_field')' – outoftime

+1

@DmitrySemenovで作成しました。ソース引数は変数ではなくメソッドを参照すると思います。前に私のコードで "source = 'author_set.count'"を持っていましたが、多くのクエリを生成していました(デバッガから見ることができます)、ほとんどのクエリが繰り返し実行され、countメソッドが呼び出されました。 – Tobias

29

受け入れられる解決策は、結果が返される回数だけデータベースにヒットします。各結果について、データベースへの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アイテムのそれぞれの著者数を取得します。

+0

一度作成したBookViewSetクラスの使い方を詳しく説明できますか?私は同じ結果を達成しようとしていますが、いったんViewSetを取得したら、どのように使用するかわかりません。 –

+3

それは受け入れられた答えでなければなりません。 – jrobichaud

関連する問題