Improve /api/v1/accounts/{id}/statuses perf (#355)

This commit is contained in:
Corry Haines 2023-01-05 21:51:02 -08:00 committed by GitHub
parent 1425ae0bde
commit be7ce6ed62
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 14 deletions

View file

@ -965,7 +965,12 @@ class Post(StatorModel):
def to_mastodon_json(self, interactions=None):
reply_parent = None
if self.in_reply_to:
reply_parent = Post.objects.filter(object_uri=self.in_reply_to).first()
# Load the PK and author.id explicitly to prevent a SELECT on the entire author Identity
reply_parent = (
Post.objects.filter(object_uri=self.in_reply_to)
.only("pk", "author_id")
.first()
)
visibility_mapping = {
self.Visibilities.public: "public",
self.Visibilities.unlisted: "unlisted",
@ -986,14 +991,7 @@ class Post(StatorModel):
attachment.to_mastodon_json() for attachment in self.attachments.all()
],
"mentions": [
{
"id": mention.id,
"username": mention.username or "",
"url": mention.absolute_profile_uri() or "",
"acct": mention.handle or "",
}
for mention in self.mentions.all()
if mention.username
mention.to_mastodon_mention_json() for mention in self.mentions.all()
],
"tags": (
[
@ -1006,13 +1004,21 @@ class Post(StatorModel):
if self.hashtags
else []
),
"emojis": [emoji.to_mastodon_json() for emoji in self.emojis.usable()],
# Filter in the list comp rather than query because the common case is no emoji in the resultset
# When filter is on emojis like `emojis.usable()` it causes a query that is not cached by prefetch_related
"emojis": [
emoji.to_mastodon_json()
for emoji in self.emojis.all()
if emoji.is_usable
],
"reblogs_count": self.stats_with_defaults["boosts"],
"favourites_count": self.stats_with_defaults["likes"],
"replies_count": self.stats_with_defaults["replies"],
"url": self.absolute_object_uri(),
"in_reply_to_id": reply_parent.pk if reply_parent else None,
"in_reply_to_account_id": reply_parent.author.pk if reply_parent else None,
"in_reply_to_account_id": (
reply_parent.author_id if reply_parent else None
),
"reblog": None,
"poll": None,
"card": None,

View file

@ -133,8 +133,15 @@ def account_statuses(
queryset = (
identity.posts.not_hidden()
.unlisted(include_replies=not exclude_replies)
.select_related("author")
.prefetch_related("attachments", "mentions__domain", "emojis")
.select_related("author", "author__domain")
.prefetch_related(
"attachments",
"mentions__domain",
"emojis",
"author__inbound_follows",
"author__outbound_follows",
"author__posts",
)
.order_by("-created")
)
if pinned:

View file

@ -812,7 +812,15 @@ class Identity(StatorModel):
### Mastodon Client API ###
def to_mastodon_json(self):
def to_mastodon_mention_json(self):
return {
"id": self.id,
"username": self.username or "",
"url": self.absolute_profile_uri() or "",
"acct": self.handle or "",
}
def to_mastodon_json(self, include_counts=True):
from activities.models import Emoji
header_image = self.local_image_url()