1

やあみんな、私はこのようなモデルを持っています:

class Interaction(DateAwareModel, UserAwareModel):
  page = models.ForeignKey(Page)
  container = models.ForeignKey(Container, blank=True, null=True)
  content = models.ForeignKey(Content)
  interaction_node = models.ForeignKey(InteractionNode)
  kind = models.CharField(max_length=3, choices=INTERACTION_TYPES)

コンテナごと、次に種類ごとにグループ化されたインタラクションの数を取得するために、1 つのクエリを実行できるようにしたいと考えています。出力 JSON データ構造 (ピストンによって処理されるシリアル化) は次のようになります。

"data": {
   "container 1": {
       "tag_count": 3, 
       "com_count": 1
   },
   "container 2": {
       "tag_count": 7, 
       "com_count": 12
   },
   ...
}

SQL は次のようになります。

SELECT container_id, kind, count(*) FROM rb_interaction GROUP BY container_id, kind;

ORM を使用して複数のフィールドでグループ化する方法についてのアイデアはありますか? (id を避けることができれば、このプロジェクトの生のクエリを書きたくありません) これは単純で一般的なクエリのようです。

質問する前に: django 集計のドキュメントと生のクエリのドキュメントを見てきました。

更新 以下のアドバイスに従って、これを処理するカスタム マネージャーを作成しました。

class ContainerManager(models.Manager):
    def get_query_set(self, *args, **kwargs):
        qs = super(ContainerManager, self).get_query_set(*args, **kwargs)
        qs.filter(Q(interaction__kind='tag') | Q(interaction__kind='com')).distinct()
        annotations = {
            'tag_count':models.Count('interaction__kind'),
            'com_count':models.Count('interaction__kind')
        }
        return qs.annotate(**annotations)

これは、group by を介してタグと com のカウントを取得する代わりに、kind tag または com のインタラクションのみをカウントします。コードからそのように動作することは明らかですが、それを修正する方法を考えています...

4

1 に答える 1

2

カスタムマネージャーを作成します。

class ContainerManager(models.Manager):
    def get_query_set(self, *args, **kwargs):
        qs = super(ContainerManager, self).get_query_set(*args, **kwargs)
        annotations = {'tag_count':models.Count('tag'), 'com_count':models.Count('com')}
        return qs.annotate(**annotations)

class Container(models.Model):
    ...
    objects = ContainerManager()

次に、Containerクエリには常に属性が含まtag_countcom_countます。参照するモデルのコピーがないため、おそらく注釈を変更する必要があります。フィールド名を推測しました。

アップデート:

したがって、モデルをよりよく理解した後は、アノテーションは探しているものに対して機能しなくなります。本当に、「タグ」または「コム」のContainersがいくつあるかをカウントする唯一の方法は次のとおりです。kind

tag_count = Container.objects.filter(kind='tag').count()
com_count = Container.objects.filter(kind='com').count()

注釈はその情報を提供しません。独自の集計や注釈を書くことは可能だと思うので、それが解決策になるかもしれません。しかし、私は自分でそれをしたことがないので、実際にあなたにガイダンスを与えることはできません。あなたはおそらくストレートSQLの使用に固執しています。

于 2011-05-24T21:45:33.937 に答える