Improves shelf page query efficiency a little

This commit is contained in:
Mouse Reeve 2021-05-22 19:54:50 -07:00
parent 7a4c4248df
commit 2d4cec4422
2 changed files with 23 additions and 12 deletions

View file

@ -13,6 +13,10 @@ from bookwyrm.utils import regex
def get_user_from_username(viewer, username): def get_user_from_username(viewer, username):
"""helper function to resolve a localname or a username to a user""" """helper function to resolve a localname or a username to a user"""
if viewer.localname == username:
# that's yourself, fool
return viewer
# raises 404 if the user isn't found # raises 404 if the user isn't found
try: try:
return models.User.viewer_aware_objects(viewer).get(localname=username) return models.User.viewer_aware_objects(viewer).get(localname=username)

View file

@ -2,7 +2,7 @@
from collections import namedtuple from collections import namedtuple
from django.db import IntegrityError from django.db import IntegrityError
from django.db.models import Count, OuterRef, Subquery, F, Q from django.db.models import OuterRef, Subquery
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator from django.core.paginator import Paginator
from django.http import HttpResponseBadRequest, HttpResponseNotFound from django.http import HttpResponseBadRequest, HttpResponseNotFound
@ -28,7 +28,12 @@ class Shelf(View):
"""display a shelf""" """display a shelf"""
user = get_user_from_username(request.user, username) user = get_user_from_username(request.user, username)
shelves = privacy_filter(request.user, user.shelf_set) is_self = user == request.user
if is_self:
shelves = user.shelf_set
else:
shelves = privacy_filter(request.user, user.shelf_set)
# get the shelf and make sure the logged in user should be able to see it # get the shelf and make sure the logged in user should be able to see it
if shelf_identifier: if shelf_identifier:
@ -53,26 +58,28 @@ class Shelf(View):
if is_api_request(request): if is_api_request(request):
return ActivitypubResponse(shelf.to_activity(**request.GET)) return ActivitypubResponse(shelf.to_activity(**request.GET))
reviews = privacy_filter( reviews = models.Review.objects.filter(
request.user, user=user,
models.Review.objects.filter( rating__isnull=False,
user=user, book__id=OuterRef("id"),
rating__isnull=False,
book__id=OuterRef("id"),
),
).order_by("-published_date") ).order_by("-published_date")
books = books.annotate(rating=Subquery(reviews.values("rating")[:1])) if not is_self:
reviews = privacy_filter(request.user, reviews)
books = books.annotate(
rating=Subquery(reviews.values("rating")[:1])
).prefetch_related("authors")
paginated = Paginator( paginated = Paginator(
books.order_by("-updated_date"), books.order_by("-shelfbook__updated_date"),
PAGE_LENGTH, PAGE_LENGTH,
) )
page = paginated.get_page(request.GET.get("page")) page = paginated.get_page(request.GET.get("page"))
data = { data = {
"user": user, "user": user,
"is_self": request.user == user, "is_self": is_self,
"shelves": shelves.all(), "shelves": shelves.all(),
"shelf": shelf, "shelf": shelf,
"books": page, "books": page,