簡體   English   中英

Django:在Queryset上使用Annotate,Count和Distinct

[英]Django: Using Annotate, Count and Distinct on a Queryset

這是我的數據庫查詢:

results = Attachments.objects.filter(currency='current').annotate(num_attachments=Count('article_id')).order_by("num_attachments").distinct('article_id')

查詢細分如下(據我所知):

  • 第一個過濾器是“當前”的當前附件。
  • 然后使用某個'article_id'計算這些附件的數量。
  • 然后使用附件編號注釋每個附件,其中包含具有共同的article_id的編號。
  • 然后根據附件數量排名。
  • 然后,使用distinct減去列表,以便每個article_id值都有一個Attachment對象。

我在PostgreSQL上運行它,所以根據Django 文檔 ,我可以根據字段運行distinct()。

執行查詢時沒有錯誤,但是當我嘗試迭代甚至打印結果時,Django調試會拋出以下錯誤:

NotImplementedError at /function/
annotate() + distinct(fields) not implemented.

交互式提示中更詳細的回溯是:

  File "<console>", line 1, in <module>
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/query.py", line 118, in _result_iter
    self._fill_cache()
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/query.py", line 875, in _fill_cache
    self._result_cache.append(self._iter.next())
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/query.py", line 291, in iterator
    for row in compiler.results_iter():
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 763, in results_iter
    for rows in self.execute_sql(MULTI):
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 808, in execute_sql
    sql, params = self.as_sql()
  File "/Users/Pat/.virtualenvs/envsp/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 107, in as_sql
    "annotate() + distinct(fields) not implemented.")
NotImplementedError: annotate() + distinct(fields) not implemented.

誰知道這里發生了什么?

解決方法是使用values('distinct_fieldname')因為這將使最終的SQL語句在該字段上執行GROUP BY (您可以添加多個字段名),這基本上是相同的。

例如,如果您想知道給定'filename'存在多少篇文章,您可以這樣做:

results = Attachments.objects.filter(currency='current').values('filename').annotate(num_attachments=Count('article_id')).order_by("num_attachments")

我找到了另一種方法,如何克服這個問題 - 使用子查詢:

distinct_articles = Attachments.objects.distinct('article_id')
results = Attachments.objects.filter(currency='current').annotate(num_attachments=Count('article_id')).order_by("num_attachments").filter(id__in=distinct_articles)

這實際上被評估為Django中的一個數據庫查詢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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