【问题标题】:What exactly posts.annotate(same_tags=Count('tags') Do?posts.annotate(same_tags=Count('tags') 到底是做什么的?
【发布时间】:2020-12-18 18:18:10
【问题描述】:

我无法弄清楚这段代码中 annotate 和 Count 究竟做了什么

similar_posts = similar_posts.annotate(same_tags=Count('tags'))

请详细解释,并以示例数据举例说明。

【问题讨论】:

标签: python sql django


【解决方案1】:

如果我正确理解您的问题。 Annotate 将在查询输出中添加一个名为 same_tags 的列字段

similar_posts = similar_posts.annotate(same_tags=Count('tags'))

如果你不提供same_tags,那么它会创建像tags__count这样的列字段

>>> from django.db.models import Avg
>>> Book.objects.all().annotate(Avg('price'))
{'price__avg': 34.35}

来自 Django 文档的片段

# Build an annotated queryset
>>> from django.db.models import Count
>>> q = Book.objects.annotate(Count('authors'))
# Interrogate the first object in the queryset
>>> q[0]
<Book: The Definitive Guide to Django>
>>> q[0].authors__count
2
# Interrogate the second object in the queryset
>>> q[1]
<Book: Practical Django Projects>
>>> q[1].authors__count
1

我正在尝试通过板和主题模型来澄清您的疑问

class Board(models.Model):
            name = models.CharField(verbose_name='name', help_text='', max_length=50, error_messages={}, db_column='name', unique=True, blank=False, null=False)
            description = models.CharField(verbose_name='description', help_text='', max_length=500, error_messages={}, db_column='description', blank=False, null=False)


class Topic(models.Model):
            subject = models.CharField(verbose_name='subject', help_text='', max_length=50, error_messages={}, db_column='subject', unique=True, blank=False, null=False)
            last_updated = models.DateTimeField(auto_now=True, help_text='', error_messages={}, db_column='last_updated', blank=False, null=False)
            board = models.ForeignKey(to=Board, on_delete=models.CASCADE, related_name='topics', related_query_name='topic', to_field='id', db_column='board', help_text='', error_messages={}, null=False, blank=False)
            starter = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='topics', related_query_name='topic', to_field='id', db_column='user', help_text='', error_messages={}, null=False, blank=False)

让我们在控制台上运行一些查询:

from boards.models import Board
all_boards =  Board.objects.all()
str(all_boards.query)
'
 SELECT "board"."id",
        "board"."name",
        "board"."description"
 FROM "board"
 ORDER BY "board"."name" ASC
'
type(all_boards)
<class 'boards.queryset.BoardQuerySet'>
all_boards
<BoardQuerySet [Angular, Python, React, Ruby]>

for board in all_boards:
...     print(board.name)
...     print(board.description)
...

Angular
This is Angular board
Python
this is python board
React
this is react board

带有注释的相同查询将在表之间进行连接。当我们想要一次从多个表中获取结果时,它会很有用

  board_anotated_with_topics =  all_boards.annotate(topics_count=Count('topic'))
    
    str(board_anotated_with_topics.query)
            
    '
    SELECT "board"."id", 
       "board"."name", 
       "board"."description", 
       COUNT("topic"."id") AS "topics_count" 
    FROM "board" 
    LEFT OUTER JOIN "topic" ON ("board"."id" = "topic"."board") 
    GROUP BY "board"."id", "board"."name", "board"."description"'
    
    for board in board_anotated_with_topics:
    ...     print("Topics in Board  = ", board.topics_count)
    ...     print("Board pk = ", board.pk)
    ...     print("Board  Name  = ", board.name)
    ...     print("Board Description", board.description)
    ...     print("#"*100)
    ...     
    
    Topics in Board  =  3
    Board pk =  3
    Board  Name  =  Angular
    Board Description This is Angular board
    ####################################################################################################
    Topics in Board  =  2
    Board pk =  1
    Board  Name  =  Python
    Board Description this is python board
    ####################################################################################################
    Topics in Board  =  2
    Board pk =  2
    Board  Name  =  React
    Board Description this is react board
    ####################################################################################################
    Topics in Board  =  2
    Board pk =  4
    Board  Name  =  Ruby
    Board Description this is Ruby  Board
    ####################################################################################################

【讨论】:

  • 对不起,你把我弄糊涂了。好的,我知道 annotate 创建了一个名为 same_tag 的新列,但 Count('Tag') 到底是做什么的???我制作了具有标签属性的帖子模型
  • 它将计算每个条目的标签数量,因为我会显示每个板块的主题数量以获取更多详细信息,请参阅w3schools.com/sql/sql_count_avg_sum.asp
猜你喜欢
  • 2015-08-06
  • 2013-09-02
  • 2014-01-02
  • 2013-10-10
  • 2017-05-08
  • 2022-01-20
  • 2012-10-17
  • 2017-06-15
  • 2011-05-20
相关资源
最近更新 更多