Django: Usando Anotar, Contar e Distinto em um Queryset

10

Aqui está minha consulta ao banco de dados:

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

A consulta é dividida da seguinte forma (como eu a entendo):

  • O primeiro filtro é o atual Anexos que são "atuais".
  • Em seguida, conte o número desses Anexos com um determinado 'article_id'.
  • Em seguida, anote cada Anexo com o número de Anexo com o número daqueles que têm artigo_id em comum.
  • Depois, classifique com base no número de anexos.
  • Em seguida, reduza a lista com distintos, para que haja um objeto de anexo para cada valor de article_id.

Eu estou rodando isso no PostgreSQL, então de acordo com os docs do Django, eu ' m bem para executar distinct () com base em um campo.

Não há erro quando executo a consulta, mas quando tento iterar ou até mesmo imprimir os resultados, o erro a seguir é lançado pelo Django debug:

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

O traceback mais detalhado do prompt interativo é:

  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.

Alguém sabe o que está acontecendo aqui?

    
por Pat 06.08.2012 в 17:42
fonte

2 respostas

5

A solução é usar values('distinct_fieldname') porque isso fará com que a instrução SQL final execute GROUP BY nesse campo (você pode adicionar mais de um nome de campo), que essencialmente é o mesmo.

Por exemplo, se você quiser saber quantos artigos existem para um determinado 'filename' , você faria isso:

results = Attachments.objects.filter(currency='current').values('filename').annotate(num_attachments=Count('article_id')).order_by("num_attachments")
    
por benjaoming 17.02.2014 / 17:10
fonte
0

Eu encontrei uma outra maneira, como superar isso - usando uma subconsulta:

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)

Isso realmente é avaliado como uma consulta de banco de dados no Django.

    
por Petr Dlouhý 03.09.2018 / 17:46
fonte