1
0
Fork 0

Merge pull request #1462 from bookwyrm-social/fewer-active-shelf-queries

Fewer active shelf queries
This commit is contained in:
Mouse Reeve 2021-09-27 13:16:50 -07:00 committed by GitHub
commit ab5521480d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 45 additions and 26 deletions

View file

@ -8,7 +8,7 @@ from django.core.files.base import ContentFile
from django.core.paginator import Paginator
from django.db import transaction
from django.db.models import Avg, Q
from django.http import HttpResponseBadRequest, HttpResponseNotFound
from django.http import HttpResponseBadRequest, Http404
from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse
from django.utils.datastructures import MultiValueDictKeyError
@ -30,25 +30,31 @@ class Book(View):
def get(self, request, book_id, user_statuses=False):
"""info about a book"""
user_statuses = user_statuses if request.user.is_authenticated else False
try:
book = models.Book.objects.select_subclasses().get(id=book_id)
except models.Book.DoesNotExist:
return HttpResponseNotFound()
if is_api_request(request):
book = get_object_or_404(
models.Book.objects.select_subclasses(), id=book_id
)
return ActivitypubResponse(book.to_activity())
if isinstance(book, models.Work):
book = book.default_edition
user_statuses = user_statuses if request.user.is_authenticated else False
# it's safe to use this OR because edition and work and subclasses of the same
# table, so they never have clashing IDs
book = (
models.Edition.viewer_aware_objects(request.user)
.filter(Q(id=book_id) | Q(parent_work__id=book_id))
.order_by("-edition_rank")
.select_related("parent_work")
.prefetch_related("authors")
.first()
)
if not book or not book.parent_work:
return HttpResponseNotFound()
raise Http404
work = book.parent_work
# all reviews for the book
# all reviews for all editions of the book
reviews = privacy_filter(
request.user, models.Review.objects.filter(book__in=work.editions.all())
request.user, models.Review.objects.filter(book__parent_work__editions=book)
)
# the reviews to show

View file

@ -168,9 +168,11 @@ def get_suggested_books(user, max_books=5):
shelf_preview = {
"name": shelf.name,
"identifier": shelf.identifier,
"books": shelf.books.order_by("shelfbook").prefetch_related("authors")[
:limit
],
"books": models.Edition.viewer_aware_objects(user)
.filter(
shelfbook__shelf=shelf,
)
.prefetch_related("authors")[:limit],
}
suggested_books.append(shelf_preview)
book_count += len(shelf_preview["books"])

View file

@ -31,9 +31,9 @@ class Shelf(View):
is_self = user == request.user
if is_self:
shelves = user.shelf_set
shelves = user.shelf_set.all()
else:
shelves = privacy_filter(request.user, user.shelf_set)
shelves = privacy_filter(request.user, user.shelf_set).all()
# get the shelf and make sure the logged in user should be able to see it
if shelf_identifier:
@ -49,10 +49,14 @@ class Shelf(View):
FakeShelf = namedtuple(
"Shelf", ("identifier", "name", "user", "books", "privacy")
)
books = models.Edition.objects.filter(
# privacy is ensured because the shelves are already filtered above
shelfbook__shelf__in=shelves.all()
).distinct()
books = (
models.Edition.viewer_aware_objects(request.user)
.filter(
# privacy is ensured because the shelves are already filtered above
shelfbook__shelf__in=shelves
)
.distinct()
)
shelf = FakeShelf("all", _("All books"), user, books, "public")
if is_api_request(request):
@ -82,7 +86,7 @@ class Shelf(View):
data = {
"user": user,
"is_self": is_self,
"shelves": shelves.all(),
"shelves": shelves,
"shelf": shelf,
"books": page,
"page_range": paginated.get_elided_page_range(