web-dev-qa-db-ja.com

Djangoクエリセットはフィールドにリスト/クエリセットになるように注釈を付けます

Djangoアノテーションを使用して、いくつかの関連するモデル属性の値のリストであるquerysetフィールドを作成しようとしています。

queryset = ...
qs = queryset.annotate(
    list_field=SomeAggregateFunction(
        Case(When(related_model__field="abc"), then="related_model__id")
    ),
    list_elements=Count(F('list_field'))
)

これらすべてのIDを区切り文字で連結することを考えていましたが、適切な関数がわかりません。別の解決策は、list_fieldをquerysetにすることです。私はこの構文が間違っていることを知っています。助けてくれてありがとう。

10
zyks

postgresqlDjango >= 1.9を使用している場合は、postgres固有の集計関数を使用できます。 ArrayAgg

配列に連結された、nullを含む値のリストを返します。

区切り文字を使用してこれらの値を連結する必要がある場合は、 StringAgg を使用することもできます。

15
AKS

私はそのようなことをしました:

qs = queryset \
    .annotate(
        field_a=ArrayAgg(Case(When(
            related_model__field="A",
            then="related_model__pk")
        )),
        field_b=ArrayAgg(Case(When(
            related_model__field="B",
            then="related_model__pk")
        )),
        field_c=ArrayAgg(Case(When(
            related_model__field="C",
            then="related_model__pk")
        ))
    )

これで、クエリセット内のすべてのオブジェクトの各field_afield_b、およびfield_cの下にNoneまたはpkのリストがあります。 Caseの代わりにNoneの他のデフォルト値を定義することもできます。

5
zyks