prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Your books: All books: shelved date is incorrect
  **Describe the bug**
  
  I just started using Bookwyrm, and added 4 books as "To Read". On my "All Books" page, the "Shelved" dates for 3 of those books are incorrect. https://bookwyrm.social/user/chorist/books
  
  If I click over to my "To Read" page however, the Shelved dates are all correct (all showing "today").
  
  **Screenshots**
  
  <img width="1181" alt="Screen Shot 2022-01-18 at 4 52 23 PM" src="https://user-images.githubusercontent.com/557851/150031715-652dc082-a45a-4e71-af7f-efc34dfb0de9.png">
  
  **Instance**
  bookwyrm.social
  
  **Desktop (please complete the following information):**
      - OS: MacOS
      - Browser: Safari
      - Version 15.2
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `bookwyrm/views/shelf/shelf.py`
  Content:
  ```
  1 """ shelf views """
  2 from collections import namedtuple
  3 
  4 from django.db.models import OuterRef, Subquery, F
  5 from django.contrib.auth.decorators import login_required
  6 from django.core.paginator import Paginator
  7 from django.http import HttpResponseBadRequest
  8 from django.shortcuts import get_object_or_404, redirect
  9 from django.template.response import TemplateResponse
  10 from django.utils.decorators import method_decorator
  11 from django.utils.translation import gettext_lazy as _
  12 from django.views import View
  13 
  14 from bookwyrm import forms, models
  15 from bookwyrm.activitypub import ActivitypubResponse
  16 from bookwyrm.settings import PAGE_LENGTH
  17 from bookwyrm.views.helpers import is_api_request, get_user_from_username
  18 
  19 
  20 # pylint: disable=no-self-use
  21 class Shelf(View):
  22     """shelf page"""
  23 
  24     def get(self, request, username, shelf_identifier=None):
  25         """display a shelf"""
  26         user = get_user_from_username(request.user, username)
  27 
  28         is_self = user == request.user
  29 
  30         if is_self:
  31             shelves = user.shelf_set.all()
  32         else:
  33             shelves = models.Shelf.privacy_filter(request.user).filter(user=user).all()
  34 
  35         # get the shelf and make sure the logged in user should be able to see it
  36         if shelf_identifier:
  37             shelf = get_object_or_404(user.shelf_set, identifier=shelf_identifier)
  38             shelf.raise_visible_to_user(request.user)
  39             books = shelf.books
  40         else:
  41             # this is a constructed "all books" view, with a fake "shelf" obj
  42             FakeShelf = namedtuple(
  43                 "Shelf", ("identifier", "name", "user", "books", "privacy")
  44             )
  45             books = (
  46                 models.Edition.viewer_aware_objects(request.user)
  47                 .filter(
  48                     # privacy is ensured because the shelves are already filtered above
  49                     shelfbook__shelf__in=shelves
  50                 )
  51                 .distinct()
  52             )
  53             shelf = FakeShelf("all", _("All books"), user, books, "public")
  54 
  55         if is_api_request(request) and shelf_identifier:
  56             return ActivitypubResponse(shelf.to_activity(**request.GET))
  57 
  58         reviews = models.Review.objects
  59         if not is_self:
  60             reviews = models.Review.privacy_filter(request.user)
  61 
  62         reviews = reviews.filter(
  63             user=user,
  64             rating__isnull=False,
  65             book__id=OuterRef("id"),
  66             deleted=False,
  67         ).order_by("-published_date")
  68 
  69         reading = models.ReadThrough.objects
  70 
  71         reading = reading.filter(user=user, book__id=OuterRef("id")).order_by(
  72             "start_date"
  73         )
  74 
  75         if shelf_identifier:
  76             books = books.annotate(shelved_date=F("shelfbook__shelved_date"))
  77         else:
  78             # sorting by shelved date will cause duplicates in the "all books" view
  79             books = books.annotate(shelved_date=F("updated_date"))
  80         books = books.annotate(
  81             rating=Subquery(reviews.values("rating")[:1]),
  82             start_date=Subquery(reading.values("start_date")[:1]),
  83             finish_date=Subquery(reading.values("finish_date")[:1]),
  84             author=Subquery(
  85                 models.Book.objects.filter(id=OuterRef("id")).values("authors__name")[
  86                     :1
  87                 ]
  88             ),
  89         ).prefetch_related("authors")
  90 
  91         books = sort_books(books, request.GET.get("sort"))
  92 
  93         paginated = Paginator(
  94             books,
  95             PAGE_LENGTH,
  96         )
  97         page = paginated.get_page(request.GET.get("page"))
  98         data = {
  99             "user": user,
  100             "is_self": is_self,
  101             "shelves": shelves,
  102             "shelf": shelf,
  103             "books": page,
  104             "edit_form": forms.ShelfForm(instance=shelf if shelf_identifier else None),
  105             "create_form": forms.ShelfForm(),
  106             "sort": request.GET.get("sort"),
  107             "page_range": paginated.get_elided_page_range(
  108                 page.number, on_each_side=2, on_ends=1
  109             ),
  110         }
  111 
  112         return TemplateResponse(request, "shelf/shelf.html", data)
  113 
  114     @method_decorator(login_required, name="dispatch")
  115     # pylint: disable=unused-argument
  116     def post(self, request, username, shelf_identifier):
  117         """edit a shelf"""
  118         user = get_user_from_username(request.user, username)
  119         shelf = get_object_or_404(user.shelf_set, identifier=shelf_identifier)
  120         shelf.raise_not_editable(request.user)
  121 
  122         # you can't change the name of the default shelves
  123         if not shelf.editable and request.POST.get("name") != shelf.name:
  124             return HttpResponseBadRequest()
  125 
  126         form = forms.ShelfForm(request.POST, instance=shelf)
  127         if not form.is_valid():
  128             return redirect(shelf.local_path)
  129         shelf = form.save()
  130         return redirect(shelf.local_path)
  131 
  132 
  133 def sort_books(books, sort):
  134     """Books in shelf sorting"""
  135     sort_fields = [
  136         "title",
  137         "author",
  138         "shelved_date",
  139         "start_date",
  140         "finish_date",
  141         "rating",
  142     ]
  143 
  144     if sort in sort_fields:
  145         books = books.order_by(sort)
  146     elif sort and sort[1:] in sort_fields:
  147         books = books.order_by(F(sort[1:]).desc(nulls_last=True))
  148     else:
  149         books = books.order_by("-shelved_date")
  150     return books
  151
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/bookwyrm/views/shelf/shelf.py b/bookwyrm/views/shelf/shelf.py
  --- a/bookwyrm/views/shelf/shelf.py
  +++ b/bookwyrm/views/shelf/shelf.py
  @@ -1,7 +1,7 @@
   """ shelf views """
   from collections import namedtuple
   
  -from django.db.models import OuterRef, Subquery, F
  +from django.db.models import OuterRef, Subquery, F, Max
   from django.contrib.auth.decorators import login_required
   from django.core.paginator import Paginator
   from django.http import HttpResponseBadRequest
  @@ -72,11 +72,7 @@
               "start_date"
           )
   
  -        if shelf_identifier:
  -            books = books.annotate(shelved_date=F("shelfbook__shelved_date"))
  -        else:
  -            # sorting by shelved date will cause duplicates in the "all books" view
  -            books = books.annotate(shelved_date=F("updated_date"))
  +        books = books.annotate(shelved_date=Max("shelfbook__shelved_date"))
           books = books.annotate(
               rating=Subquery(reviews.values("rating")[:1]),
               start_date=Subquery(reading.values("start_date")[:1]),
  
verification_info: {"golden_diff": "diff --git a/bookwyrm/views/shelf/shelf.py b/bookwyrm/views/shelf/shelf.py\n--- a/bookwyrm/views/shelf/shelf.py\n+++ b/bookwyrm/views/shelf/shelf.py\n@@ -1,7 +1,7 @@\n \"\"\" shelf views \"\"\"\n from collections import namedtuple\n \n-from django.db.models import OuterRef, Subquery, F\n+from django.db.models import OuterRef, Subquery, F, Max\n from django.contrib.auth.decorators import login_required\n from django.core.paginator import Paginator\n from django.http import HttpResponseBadRequest\n@@ -72,11 +72,7 @@\n             \"start_date\"\n         )\n \n-        if shelf_identifier:\n-            books = books.annotate(shelved_date=F(\"shelfbook__shelved_date\"))\n-        else:\n-            # sorting by shelved date will cause duplicates in the \"all books\" view\n-            books = books.annotate(shelved_date=F(\"updated_date\"))\n+        books = books.annotate(shelved_date=Max(\"shelfbook__shelved_date\"))\n         books = books.annotate(\n             rating=Subquery(reviews.values(\"rating\")[:1]),\n             start_date=Subquery(reading.values(\"start_date\")[:1]),\n", "issue": "Your books: All books: shelved date is incorrect\n**Describe the bug**\r\n\r\nI just started using Bookwyrm, and added 4 books as \"To Read\". On my \"All Books\" page, the \"Shelved\" dates for 3 of those books are incorrect. https://bookwyrm.social/user/chorist/books\r\n\r\nIf I click over to my \"To Read\" page however, the Shelved dates are all correct (all showing \"today\").\r\n\r\n**Screenshots**\r\n\r\n<img width=\"1181\" alt=\"Screen Shot 2022-01-18 at 4 52 23 PM\" src=\"https://user-images.githubusercontent.com/557851/150031715-652dc082-a45a-4e71-af7f-efc34dfb0de9.png\">\r\n\r\n**Instance**\r\nbookwyrm.social\r\n\r\n**Desktop (please complete the following information):**\r\n    - OS: MacOS\r\n    - Browser: Safari\r\n    - Version 15.2\r\n\r\n\n", "before_files": [{"content": "\"\"\" shelf views \"\"\"\nfrom collections import namedtuple\n\nfrom django.db.models import OuterRef, Subquery, F\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.paginator import Paginator\nfrom django.http import HttpResponseBadRequest\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.utils.decorators import method_decorator\nfrom django.utils.translation import gettext_lazy as _\nfrom django.views import View\n\nfrom bookwyrm import forms, models\nfrom bookwyrm.activitypub import ActivitypubResponse\nfrom bookwyrm.settings import PAGE_LENGTH\nfrom bookwyrm.views.helpers import is_api_request, get_user_from_username\n\n\n# pylint: disable=no-self-use\nclass Shelf(View):\n    \"\"\"shelf page\"\"\"\n\n    def get(self, request, username, shelf_identifier=None):\n        \"\"\"display a shelf\"\"\"\n        user = get_user_from_username(request.user, username)\n\n        is_self = user == request.user\n\n        if is_self:\n            shelves = user.shelf_set.all()\n        else:\n            shelves = models.Shelf.privacy_filter(request.user).filter(user=user).all()\n\n        # get the shelf and make sure the logged in user should be able to see it\n        if shelf_identifier:\n            shelf = get_object_or_404(user.shelf_set, identifier=shelf_identifier)\n            shelf.raise_visible_to_user(request.user)\n            books = shelf.books\n        else:\n            # this is a constructed \"all books\" view, with a fake \"shelf\" obj\n            FakeShelf = namedtuple(\n                \"Shelf\", (\"identifier\", \"name\", \"user\", \"books\", \"privacy\")\n            )\n            books = (\n                models.Edition.viewer_aware_objects(request.user)\n                .filter(\n                    # privacy is ensured because the shelves are already filtered above\n                    shelfbook__shelf__in=shelves\n                )\n                .distinct()\n            )\n            shelf = FakeShelf(\"all\", _(\"All books\"), user, books, \"public\")\n\n        if is_api_request(request) and shelf_identifier:\n            return ActivitypubResponse(shelf.to_activity(**request.GET))\n\n        reviews = models.Review.objects\n        if not is_self:\n            reviews = models.Review.privacy_filter(request.user)\n\n        reviews = reviews.filter(\n            user=user,\n            rating__isnull=False,\n            book__id=OuterRef(\"id\"),\n            deleted=False,\n        ).order_by(\"-published_date\")\n\n        reading = models.ReadThrough.objects\n\n        reading = reading.filter(user=user, book__id=OuterRef(\"id\")).order_by(\n            \"start_date\"\n        )\n\n        if shelf_identifier:\n            books = books.annotate(shelved_date=F(\"shelfbook__shelved_date\"))\n        else:\n            # sorting by shelved date will cause duplicates in the \"all books\" view\n            books = books.annotate(shelved_date=F(\"updated_date\"))\n        books = books.annotate(\n            rating=Subquery(reviews.values(\"rating\")[:1]),\n            start_date=Subquery(reading.values(\"start_date\")[:1]),\n            finish_date=Subquery(reading.values(\"finish_date\")[:1]),\n            author=Subquery(\n                models.Book.objects.filter(id=OuterRef(\"id\")).values(\"authors__name\")[\n                    :1\n                ]\n            ),\n        ).prefetch_related(\"authors\")\n\n        books = sort_books(books, request.GET.get(\"sort\"))\n\n        paginated = Paginator(\n            books,\n            PAGE_LENGTH,\n        )\n        page = paginated.get_page(request.GET.get(\"page\"))\n        data = {\n            \"user\": user,\n            \"is_self\": is_self,\n            \"shelves\": shelves,\n            \"shelf\": shelf,\n            \"books\": page,\n            \"edit_form\": forms.ShelfForm(instance=shelf if shelf_identifier else None),\n            \"create_form\": forms.ShelfForm(),\n            \"sort\": request.GET.get(\"sort\"),\n            \"page_range\": paginated.get_elided_page_range(\n                page.number, on_each_side=2, on_ends=1\n            ),\n        }\n\n        return TemplateResponse(request, \"shelf/shelf.html\", data)\n\n    @method_decorator(login_required, name=\"dispatch\")\n    # pylint: disable=unused-argument\n    def post(self, request, username, shelf_identifier):\n        \"\"\"edit a shelf\"\"\"\n        user = get_user_from_username(request.user, username)\n        shelf = get_object_or_404(user.shelf_set, identifier=shelf_identifier)\n        shelf.raise_not_editable(request.user)\n\n        # you can't change the name of the default shelves\n        if not shelf.editable and request.POST.get(\"name\") != shelf.name:\n            return HttpResponseBadRequest()\n\n        form = forms.ShelfForm(request.POST, instance=shelf)\n        if not form.is_valid():\n            return redirect(shelf.local_path)\n        shelf = form.save()\n        return redirect(shelf.local_path)\n\n\ndef sort_books(books, sort):\n    \"\"\"Books in shelf sorting\"\"\"\n    sort_fields = [\n        \"title\",\n        \"author\",\n        \"shelved_date\",\n        \"start_date\",\n        \"finish_date\",\n        \"rating\",\n    ]\n\n    if sort in sort_fields:\n        books = books.order_by(sort)\n    elif sort and sort[1:] in sort_fields:\n        books = books.order_by(F(sort[1:]).desc(nulls_last=True))\n    else:\n        books = books.order_by(\"-shelved_date\")\n    return books\n", "path": "bookwyrm/views/shelf/shelf.py"}], "after_files": [{"content": "\"\"\" shelf views \"\"\"\nfrom collections import namedtuple\n\nfrom django.db.models import OuterRef, Subquery, F, Max\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.paginator import Paginator\nfrom django.http import HttpResponseBadRequest\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.utils.decorators import method_decorator\nfrom django.utils.translation import gettext_lazy as _\nfrom django.views import View\n\nfrom bookwyrm import forms, models\nfrom bookwyrm.activitypub import ActivitypubResponse\nfrom bookwyrm.settings import PAGE_LENGTH\nfrom bookwyrm.views.helpers import is_api_request, get_user_from_username\n\n\n# pylint: disable=no-self-use\nclass Shelf(View):\n    \"\"\"shelf page\"\"\"\n\n    def get(self, request, username, shelf_identifier=None):\n        \"\"\"display a shelf\"\"\"\n        user = get_user_from_username(request.user, username)\n\n        is_self = user == request.user\n\n        if is_self:\n            shelves = user.shelf_set.all()\n        else:\n            shelves = models.Shelf.privacy_filter(request.user).filter(user=user).all()\n\n        # get the shelf and make sure the logged in user should be able to see it\n        if shelf_identifier:\n            shelf = get_object_or_404(user.shelf_set, identifier=shelf_identifier)\n            shelf.raise_visible_to_user(request.user)\n            books = shelf.books\n        else:\n            # this is a constructed \"all books\" view, with a fake \"shelf\" obj\n            FakeShelf = namedtuple(\n                \"Shelf\", (\"identifier\", \"name\", \"user\", \"books\", \"privacy\")\n            )\n            books = (\n                models.Edition.viewer_aware_objects(request.user)\n                .filter(\n                    # privacy is ensured because the shelves are already filtered above\n                    shelfbook__shelf__in=shelves\n                )\n                .distinct()\n            )\n            shelf = FakeShelf(\"all\", _(\"All books\"), user, books, \"public\")\n\n        if is_api_request(request) and shelf_identifier:\n            return ActivitypubResponse(shelf.to_activity(**request.GET))\n\n        reviews = models.Review.objects\n        if not is_self:\n            reviews = models.Review.privacy_filter(request.user)\n\n        reviews = reviews.filter(\n            user=user,\n            rating__isnull=False,\n            book__id=OuterRef(\"id\"),\n            deleted=False,\n        ).order_by(\"-published_date\")\n\n        reading = models.ReadThrough.objects\n\n        reading = reading.filter(user=user, book__id=OuterRef(\"id\")).order_by(\n            \"start_date\"\n        )\n\n        books = books.annotate(shelved_date=Max(\"shelfbook__shelved_date\"))\n        books = books.annotate(\n            rating=Subquery(reviews.values(\"rating\")[:1]),\n            start_date=Subquery(reading.values(\"start_date\")[:1]),\n            finish_date=Subquery(reading.values(\"finish_date\")[:1]),\n            author=Subquery(\n                models.Book.objects.filter(id=OuterRef(\"id\")).values(\"authors__name\")[\n                    :1\n                ]\n            ),\n        ).prefetch_related(\"authors\")\n\n        books = sort_books(books, request.GET.get(\"sort\"))\n\n        paginated = Paginator(\n            books,\n            PAGE_LENGTH,\n        )\n        page = paginated.get_page(request.GET.get(\"page\"))\n        data = {\n            \"user\": user,\n            \"is_self\": is_self,\n            \"shelves\": shelves,\n            \"shelf\": shelf,\n            \"books\": page,\n            \"edit_form\": forms.ShelfForm(instance=shelf if shelf_identifier else None),\n            \"create_form\": forms.ShelfForm(),\n            \"sort\": request.GET.get(\"sort\"),\n            \"page_range\": paginated.get_elided_page_range(\n                page.number, on_each_side=2, on_ends=1\n            ),\n        }\n\n        return TemplateResponse(request, \"shelf/shelf.html\", data)\n\n    @method_decorator(login_required, name=\"dispatch\")\n    # pylint: disable=unused-argument\n    def post(self, request, username, shelf_identifier):\n        \"\"\"edit a shelf\"\"\"\n        user = get_user_from_username(request.user, username)\n        shelf = get_object_or_404(user.shelf_set, identifier=shelf_identifier)\n        shelf.raise_not_editable(request.user)\n\n        # you can't change the name of the default shelves\n        if not shelf.editable and request.POST.get(\"name\") != shelf.name:\n            return HttpResponseBadRequest()\n\n        form = forms.ShelfForm(request.POST, instance=shelf)\n        if not form.is_valid():\n            return redirect(shelf.local_path)\n        shelf = form.save()\n        return redirect(shelf.local_path)\n\n\ndef sort_books(books, sort):\n    \"\"\"Books in shelf sorting\"\"\"\n    sort_fields = [\n        \"title\",\n        \"author\",\n        \"shelved_date\",\n        \"start_date\",\n        \"finish_date\",\n        \"rating\",\n    ]\n\n    if sort in sort_fields:\n        books = books.order_by(sort)\n    elif sort and sort[1:] in sort_fields:\n        books = books.order_by(F(sort[1:]).desc(nulls_last=True))\n    else:\n        books = books.order_by(\"-shelved_date\")\n    return books\n", "path": "bookwyrm/views/shelf/shelf.py"}]}