【发布时间】:2020-12-18 18:18:10
【问题描述】:
我无法弄清楚这段代码中 annotate 和 Count 究竟做了什么
similar_posts = similar_posts.annotate(same_tags=Count('tags'))
请详细解释,并以示例数据举例说明。
【问题讨论】:
我无法弄清楚这段代码中 annotate 和 Count 究竟做了什么
similar_posts = similar_posts.annotate(same_tags=Count('tags'))
请详细解释,并以示例数据举例说明。
【问题讨论】:
如果我正确理解您的问题。 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
####################################################################################################
【讨论】: