prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Switching editions changes "shelved" date
  **Describe the bug**
  When switching editions of a book already on your "To Read" list, the "shelved" date is changed to today's date.
  
  **To Reproduce**
  Steps to reproduce the behavior:
  1. Pick any book on your "To read" list with more than one edition
  2. Pick another edition and switch to this
  3. Observe that the book's shelved date is now today
  
  **Expected behavior**
  This shouldn't changed the shelved date
  
  **Instance**
  https://books.theunseen.city
  
  ---
  
  **Desktop (please complete the following information):**
      - OS: MacOS 14.1
      - Browser: Firefox
      - Version: 20.0 (64-bit)
  
  
  --- 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/books/editions.py`
  Content:
  ```
  1 """ the good stuff! the books! """
  2 from functools import reduce
  3 import operator
  4 
  5 from django.contrib.auth.decorators import login_required
  6 from django.core.paginator import Paginator
  7 from django.db import transaction
  8 from django.db.models import Q
  9 from django.shortcuts import get_object_or_404, redirect
  10 from django.template.response import TemplateResponse
  11 from django.views import View
  12 from django.views.decorators.http import require_POST
  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
  18 
  19 
  20 # pylint: disable=no-self-use
  21 class Editions(View):
  22     """list of editions"""
  23 
  24     def get(self, request, book_id):
  25         """list of editions of a book"""
  26         work = get_object_or_404(models.Work, id=book_id)
  27 
  28         if is_api_request(request):
  29             return ActivitypubResponse(work.to_edition_list(**request.GET))
  30         filters = {}
  31 
  32         if request.GET.get("language"):
  33             filters["languages__contains"] = [request.GET.get("language")]
  34         if request.GET.get("format"):
  35             filters["physical_format__iexact"] = request.GET.get("format")
  36 
  37         editions = work.editions.order_by("-edition_rank")
  38         languages = set(sum(editions.values_list("languages", flat=True), []))
  39 
  40         editions = editions.filter(**filters)
  41 
  42         query = request.GET.get("q")
  43         if query:
  44             searchable_array_fields = ["languages", "publishers"]
  45             searchable_fields = [
  46                 "title",
  47                 "physical_format",
  48                 "isbn_10",
  49                 "isbn_13",
  50                 "oclc_number",
  51                 "asin",
  52                 "aasin",
  53                 "isfdb",
  54             ]
  55             search_filter_entries = [
  56                 {f"{f}__icontains": query} for f in searchable_fields
  57             ] + [{f"{f}__iexact": query} for f in searchable_array_fields]
  58             editions = editions.filter(
  59                 reduce(operator.or_, (Q(**f) for f in search_filter_entries))
  60             )
  61 
  62         paginated = Paginator(editions, PAGE_LENGTH)
  63         page = paginated.get_page(request.GET.get("page"))
  64         data = {
  65             "editions": page,
  66             "page_range": paginated.get_elided_page_range(
  67                 page.number, on_each_side=2, on_ends=1
  68             ),
  69             "work": work,
  70             "work_form": forms.EditionFromWorkForm(instance=work),
  71             "languages": languages,
  72             "formats": set(
  73                 e.physical_format.lower() for e in editions if e.physical_format
  74             ),
  75         }
  76         return TemplateResponse(request, "book/editions/editions.html", data)
  77 
  78 
  79 @login_required
  80 @require_POST
  81 @transaction.atomic
  82 def switch_edition(request):
  83     """switch your copy of a book to a different edition"""
  84     edition_id = request.POST.get("edition")
  85     new_edition = get_object_or_404(models.Edition, id=edition_id)
  86     shelfbooks = models.ShelfBook.objects.filter(
  87         book__parent_work=new_edition.parent_work, shelf__user=request.user
  88     )
  89     for shelfbook in shelfbooks.all():
  90         with transaction.atomic():
  91             models.ShelfBook.objects.create(
  92                 created_date=shelfbook.created_date,
  93                 user=shelfbook.user,
  94                 shelf=shelfbook.shelf,
  95                 book=new_edition,
  96             )
  97             shelfbook.delete()
  98 
  99     readthroughs = models.ReadThrough.objects.filter(
  100         book__parent_work=new_edition.parent_work, user=request.user
  101     )
  102     for readthrough in readthroughs.all():
  103         readthrough.book = new_edition
  104         readthrough.save()
  105 
  106     return redirect(f"/book/{new_edition.id}")
  107
  ```
  --- 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/books/editions.py b/bookwyrm/views/books/editions.py
  --- a/bookwyrm/views/books/editions.py
  +++ b/bookwyrm/views/books/editions.py
  @@ -93,6 +93,7 @@
                   user=shelfbook.user,
                   shelf=shelfbook.shelf,
                   book=new_edition,
  +                shelved_date=shelfbook.shelved_date,
               )
               shelfbook.delete()
  
verification_info: {"golden_diff": "diff --git a/bookwyrm/views/books/editions.py b/bookwyrm/views/books/editions.py\n--- a/bookwyrm/views/books/editions.py\n+++ b/bookwyrm/views/books/editions.py\n@@ -93,6 +93,7 @@\n                 user=shelfbook.user,\n                 shelf=shelfbook.shelf,\n                 book=new_edition,\n+                shelved_date=shelfbook.shelved_date,\n             )\n             shelfbook.delete()\n", "issue": "Switching editions changes \"shelved\" date\n**Describe the bug**\r\nWhen switching editions of a book already on your \"To Read\" list, the \"shelved\" date is changed to today's date.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Pick any book on your \"To read\" list with more than one edition\r\n2. Pick another edition and switch to this\r\n3. Observe that the book's shelved date is now today\r\n\r\n**Expected behavior**\r\nThis shouldn't changed the shelved date\r\n\r\n**Instance**\r\nhttps://books.theunseen.city\r\n\r\n---\r\n\r\n**Desktop (please complete the following information):**\r\n    - OS: MacOS 14.1\r\n    - Browser: Firefox\r\n    - Version: 20.0 (64-bit)\r\n\n", "before_files": [{"content": "\"\"\" the good stuff! the books! \"\"\"\nfrom functools import reduce\nimport operator\n\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.paginator import Paginator\nfrom django.db import transaction\nfrom django.db.models import Q\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.views import View\nfrom django.views.decorators.http import require_POST\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\n\n\n# pylint: disable=no-self-use\nclass Editions(View):\n    \"\"\"list of editions\"\"\"\n\n    def get(self, request, book_id):\n        \"\"\"list of editions of a book\"\"\"\n        work = get_object_or_404(models.Work, id=book_id)\n\n        if is_api_request(request):\n            return ActivitypubResponse(work.to_edition_list(**request.GET))\n        filters = {}\n\n        if request.GET.get(\"language\"):\n            filters[\"languages__contains\"] = [request.GET.get(\"language\")]\n        if request.GET.get(\"format\"):\n            filters[\"physical_format__iexact\"] = request.GET.get(\"format\")\n\n        editions = work.editions.order_by(\"-edition_rank\")\n        languages = set(sum(editions.values_list(\"languages\", flat=True), []))\n\n        editions = editions.filter(**filters)\n\n        query = request.GET.get(\"q\")\n        if query:\n            searchable_array_fields = [\"languages\", \"publishers\"]\n            searchable_fields = [\n                \"title\",\n                \"physical_format\",\n                \"isbn_10\",\n                \"isbn_13\",\n                \"oclc_number\",\n                \"asin\",\n                \"aasin\",\n                \"isfdb\",\n            ]\n            search_filter_entries = [\n                {f\"{f}__icontains\": query} for f in searchable_fields\n            ] + [{f\"{f}__iexact\": query} for f in searchable_array_fields]\n            editions = editions.filter(\n                reduce(operator.or_, (Q(**f) for f in search_filter_entries))\n            )\n\n        paginated = Paginator(editions, PAGE_LENGTH)\n        page = paginated.get_page(request.GET.get(\"page\"))\n        data = {\n            \"editions\": page,\n            \"page_range\": paginated.get_elided_page_range(\n                page.number, on_each_side=2, on_ends=1\n            ),\n            \"work\": work,\n            \"work_form\": forms.EditionFromWorkForm(instance=work),\n            \"languages\": languages,\n            \"formats\": set(\n                e.physical_format.lower() for e in editions if e.physical_format\n            ),\n        }\n        return TemplateResponse(request, \"book/editions/editions.html\", data)\n\n\n@login_required\n@require_POST\n@transaction.atomic\ndef switch_edition(request):\n    \"\"\"switch your copy of a book to a different edition\"\"\"\n    edition_id = request.POST.get(\"edition\")\n    new_edition = get_object_or_404(models.Edition, id=edition_id)\n    shelfbooks = models.ShelfBook.objects.filter(\n        book__parent_work=new_edition.parent_work, shelf__user=request.user\n    )\n    for shelfbook in shelfbooks.all():\n        with transaction.atomic():\n            models.ShelfBook.objects.create(\n                created_date=shelfbook.created_date,\n                user=shelfbook.user,\n                shelf=shelfbook.shelf,\n                book=new_edition,\n            )\n            shelfbook.delete()\n\n    readthroughs = models.ReadThrough.objects.filter(\n        book__parent_work=new_edition.parent_work, user=request.user\n    )\n    for readthrough in readthroughs.all():\n        readthrough.book = new_edition\n        readthrough.save()\n\n    return redirect(f\"/book/{new_edition.id}\")\n", "path": "bookwyrm/views/books/editions.py"}], "after_files": [{"content": "\"\"\" the good stuff! the books! \"\"\"\nfrom functools import reduce\nimport operator\n\nfrom django.contrib.auth.decorators import login_required\nfrom django.core.paginator import Paginator\nfrom django.db import transaction\nfrom django.db.models import Q\nfrom django.shortcuts import get_object_or_404, redirect\nfrom django.template.response import TemplateResponse\nfrom django.views import View\nfrom django.views.decorators.http import require_POST\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\n\n\n# pylint: disable=no-self-use\nclass Editions(View):\n    \"\"\"list of editions\"\"\"\n\n    def get(self, request, book_id):\n        \"\"\"list of editions of a book\"\"\"\n        work = get_object_or_404(models.Work, id=book_id)\n\n        if is_api_request(request):\n            return ActivitypubResponse(work.to_edition_list(**request.GET))\n        filters = {}\n\n        if request.GET.get(\"language\"):\n            filters[\"languages__contains\"] = [request.GET.get(\"language\")]\n        if request.GET.get(\"format\"):\n            filters[\"physical_format__iexact\"] = request.GET.get(\"format\")\n\n        editions = work.editions.order_by(\"-edition_rank\")\n        languages = set(sum(editions.values_list(\"languages\", flat=True), []))\n\n        editions = editions.filter(**filters)\n\n        query = request.GET.get(\"q\")\n        if query:\n            searchable_array_fields = [\"languages\", \"publishers\"]\n            searchable_fields = [\n                \"title\",\n                \"physical_format\",\n                \"isbn_10\",\n                \"isbn_13\",\n                \"oclc_number\",\n                \"asin\",\n                \"aasin\",\n                \"isfdb\",\n            ]\n            search_filter_entries = [\n                {f\"{f}__icontains\": query} for f in searchable_fields\n            ] + [{f\"{f}__iexact\": query} for f in searchable_array_fields]\n            editions = editions.filter(\n                reduce(operator.or_, (Q(**f) for f in search_filter_entries))\n            )\n\n        paginated = Paginator(editions, PAGE_LENGTH)\n        page = paginated.get_page(request.GET.get(\"page\"))\n        data = {\n            \"editions\": page,\n            \"page_range\": paginated.get_elided_page_range(\n                page.number, on_each_side=2, on_ends=1\n            ),\n            \"work\": work,\n            \"work_form\": forms.EditionFromWorkForm(instance=work),\n            \"languages\": languages,\n            \"formats\": set(\n                e.physical_format.lower() for e in editions if e.physical_format\n            ),\n        }\n        return TemplateResponse(request, \"book/editions/editions.html\", data)\n\n\n@login_required\n@require_POST\n@transaction.atomic\ndef switch_edition(request):\n    \"\"\"switch your copy of a book to a different edition\"\"\"\n    edition_id = request.POST.get(\"edition\")\n    new_edition = get_object_or_404(models.Edition, id=edition_id)\n    shelfbooks = models.ShelfBook.objects.filter(\n        book__parent_work=new_edition.parent_work, shelf__user=request.user\n    )\n    for shelfbook in shelfbooks.all():\n        with transaction.atomic():\n            models.ShelfBook.objects.create(\n                created_date=shelfbook.created_date,\n                user=shelfbook.user,\n                shelf=shelfbook.shelf,\n                book=new_edition,\n                shelved_date=shelfbook.shelved_date,\n            )\n            shelfbook.delete()\n\n    readthroughs = models.ReadThrough.objects.filter(\n        book__parent_work=new_edition.parent_work, user=request.user\n    )\n    for readthrough in readthroughs.all():\n        readthrough.book = new_edition\n        readthrough.save()\n\n    return redirect(f\"/book/{new_edition.id}\")\n", "path": "bookwyrm/views/books/editions.py"}]}