We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Certain Genre Detail pages are _very_ slow to load
I think the problem is trying to display the "chants by genre" table - for a genre with lots of example chants, e.g. [Antiphon](http://206.12.88.113/genre/122), I've tried loading the page several times and keep getting a 502 error.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `django/cantusdb_project/main_app/views/genre.py`
Content:
```
1 from typing import Dict, List
2 
3 from django.views.generic import ListView
4 from django.views.generic.detail import SingleObjectMixin
5 from extra_views import SearchableListMixin
6 from main_app.models import Genre
7 
8 
9 class GenreDetailView(SingleObjectMixin, ListView):
10     paginate_by = 100
11     template_name = "genre_detail.html"
12 
13     def get_genre_cantus_ids(self, display_unpublished=True) -> List[Dict]:
14         """
15         Get a list with data on each unique ``cantus_id`` related to this Genre.
16 
17         The list contains dicts and each dict has the following keys:
18 
19         ``cantus_id``: The ``cantus_id``
20         ``num_chants``: The number of Chants that have this ``cantus_id``
21         ``first_incipit``: The incipit of first Chant with this ``cantus_id``
22         ``first_incipit_url``: The url of first Chant with this ``cantus_id``
23 
24         Returns:
25             List[Dict]: A list of dicts with data on each unique ``cantus_id``
26         """
27         cantus_ids = (self.object.chant_set
28             .exclude(cantus_id=None)
29             .values_list("cantus_id", flat=True)
30             .distinct("cantus_id")
31         )
32         if not display_unpublished:
33             cantus_ids = cantus_ids.filter(source__published=True)
34         
35         cantus_ids_list = list(cantus_ids)
36 
37         chant_list = []
38         for cantus_id in cantus_ids_list:
39             chants = self.object.chant_set.filter(cantus_id=cantus_id)
40             num_chants = chants.count()
41             first_chant = chants.first()
42             first_incipit_url = first_chant.get_absolute_url()
43             first_incipit = first_chant.incipit
44             chant_list.append(
45                 {
46                     "cantus_id": cantus_id,
47                     "num_chants": num_chants,
48                     "first_incipit": first_incipit,
49                     "first_incipit_url": first_incipit_url,
50                 }
51             )
52         # Sort list based on number of Chants per cantus_id (descending)
53         chant_list = sorted(chant_list, key=lambda k: k["num_chants"], reverse=True)
54         return chant_list
55 
56     def get(self, request, *args, **kwargs):
57         self.object = self.get_object(queryset=Genre.objects.all())
58         return super().get(request, *args, **kwargs)
59 
60     def get_context_data(self, **kwargs):
61         context = super().get_context_data(**kwargs)
62         context["genre"] = self.object
63         return context
64 
65     def get_queryset(self):
66         display_unpublished = self.request.user.is_authenticated
67         search_term = self.request.GET.get("incipit")
68         if not search_term:
69             return self.get_genre_cantus_ids(display_unpublished=display_unpublished)
70         else:
71             search_term = search_term.strip(" ")
72             filtered_chants = [
73                 chant
74                 for chant in self.get_genre_cantus_ids(display_unpublished=display_unpublished)
75                 if search_term.lower() in chant["first_incipit"].lower()
76             ]
77             return filtered_chants
78 
79 
80 class GenreListView(SearchableListMixin, ListView):
81     model = Genre
82     paginate_by = 100
83     context_object_name = "genres"
84     template_name = "genre_list.html"
85 
86     def get_queryset(self):
87         queryset = super().get_queryset()
88         mass_office = self.request.GET.get("mass_office", None)
89         if mass_office in ["Mass", "Office", "Old Hispanic"]:
90             queryset = queryset.filter(mass_office__contains=mass_office)
91         return queryset.order_by("name")
92
```
--- 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()

```

diff --git a/django/cantusdb_project/main_app/views/genre.py b/django/cantusdb_project/main_app/views/genre.py
--- a/django/cantusdb_project/main_app/views/genre.py
+++ b/django/cantusdb_project/main_app/views/genre.py
@@ -1,81 +1,13 @@
-from typing import Dict, List
-
-from django.views.generic import ListView
-from django.views.generic.detail import SingleObjectMixin
+from django.views.generic import DetailView, ListView
 from extra_views import SearchableListMixin
 from main_app.models import Genre
 
 
-class GenreDetailView(SingleObjectMixin, ListView):
-    paginate_by = 100
+class GenreDetailView(DetailView):
+    model = Genre
+    context_object_name = "genre"
     template_name = "genre_detail.html"
 
-    def get_genre_cantus_ids(self, display_unpublished=True) -> List[Dict]:
-        """
-        Get a list with data on each unique ``cantus_id`` related to this Genre.
-
-        The list contains dicts and each dict has the following keys:
-
-        ``cantus_id``: The ``cantus_id``
-        ``num_chants``: The number of Chants that have this ``cantus_id``
-        ``first_incipit``: The incipit of first Chant with this ``cantus_id``
-        ``first_incipit_url``: The url of first Chant with this ``cantus_id``
-
-        Returns:
-            List[Dict]: A list of dicts with data on each unique ``cantus_id``
-        """
-        cantus_ids = (self.object.chant_set
-            .exclude(cantus_id=None)
-            .values_list("cantus_id", flat=True)
-            .distinct("cantus_id")
-        )
-        if not display_unpublished:
-            cantus_ids = cantus_ids.filter(source__published=True)
-        
-        cantus_ids_list = list(cantus_ids)
-
-        chant_list = []
-        for cantus_id in cantus_ids_list:
-            chants = self.object.chant_set.filter(cantus_id=cantus_id)
-            num_chants = chants.count()
-            first_chant = chants.first()
-            first_incipit_url = first_chant.get_absolute_url()
-            first_incipit = first_chant.incipit
-            chant_list.append(
-                {
-                    "cantus_id": cantus_id,
-                    "num_chants": num_chants,
-                    "first_incipit": first_incipit,
-                    "first_incipit_url": first_incipit_url,
-                }
-            )
-        # Sort list based on number of Chants per cantus_id (descending)
-        chant_list = sorted(chant_list, key=lambda k: k["num_chants"], reverse=True)
-        return chant_list
-
-    def get(self, request, *args, **kwargs):
-        self.object = self.get_object(queryset=Genre.objects.all())
-        return super().get(request, *args, **kwargs)
-
-    def get_context_data(self, **kwargs):
-        context = super().get_context_data(**kwargs)
-        context["genre"] = self.object
-        return context
-
-    def get_queryset(self):
-        display_unpublished = self.request.user.is_authenticated
-        search_term = self.request.GET.get("incipit")
-        if not search_term:
-            return self.get_genre_cantus_ids(display_unpublished=display_unpublished)
-        else:
-            search_term = search_term.strip(" ")
-            filtered_chants = [
-                chant
-                for chant in self.get_genre_cantus_ids(display_unpublished=display_unpublished)
-                if search_term.lower() in chant["first_incipit"].lower()
-            ]
-            return filtered_chants
-
 
 class GenreListView(SearchableListMixin, ListView):
     model = Genre

{"golden_diff": "diff --git a/django/cantusdb_project/main_app/views/genre.py b/django/cantusdb_project/main_app/views/genre.py\n--- a/django/cantusdb_project/main_app/views/genre.py\n+++ b/django/cantusdb_project/main_app/views/genre.py\n@@ -1,81 +1,13 @@\n-from typing import Dict, List\n-\n-from django.views.generic import ListView\n-from django.views.generic.detail import SingleObjectMixin\n+from django.views.generic import DetailView, ListView\n from extra_views import SearchableListMixin\n from main_app.models import Genre\n \n \n-class GenreDetailView(SingleObjectMixin, ListView):\n-    paginate_by = 100\n+class GenreDetailView(DetailView):\n+    model = Genre\n+    context_object_name = \"genre\"\n     template_name = \"genre_detail.html\"\n \n-    def get_genre_cantus_ids(self, display_unpublished=True) -> List[Dict]:\n-        \"\"\"\n-        Get a list with data on each unique ``cantus_id`` related to this Genre.\n-\n-        The list contains dicts and each dict has the following keys:\n-\n-        ``cantus_id``: The ``cantus_id``\n-        ``num_chants``: The number of Chants that have this ``cantus_id``\n-        ``first_incipit``: The incipit of first Chant with this ``cantus_id``\n-        ``first_incipit_url``: The url of first Chant with this ``cantus_id``\n-\n-        Returns:\n-            List[Dict]: A list of dicts with data on each unique ``cantus_id``\n-        \"\"\"\n-        cantus_ids = (self.object.chant_set\n-            .exclude(cantus_id=None)\n-            .values_list(\"cantus_id\", flat=True)\n-            .distinct(\"cantus_id\")\n-        )\n-        if not display_unpublished:\n-            cantus_ids = cantus_ids.filter(source__published=True)\n-        \n-        cantus_ids_list = list(cantus_ids)\n-\n-        chant_list = []\n-        for cantus_id in cantus_ids_list:\n-            chants = self.object.chant_set.filter(cantus_id=cantus_id)\n-            num_chants = chants.count()\n-            first_chant = chants.first()\n-            first_incipit_url = first_chant.get_absolute_url()\n-            first_incipit = first_chant.incipit\n-            chant_list.append(\n-                {\n-                    \"cantus_id\": cantus_id,\n-                    \"num_chants\": num_chants,\n-                    \"first_incipit\": first_incipit,\n-                    \"first_incipit_url\": first_incipit_url,\n-                }\n-            )\n-        # Sort list based on number of Chants per cantus_id (descending)\n-        chant_list = sorted(chant_list, key=lambda k: k[\"num_chants\"], reverse=True)\n-        return chant_list\n-\n-    def get(self, request, *args, **kwargs):\n-        self.object = self.get_object(queryset=Genre.objects.all())\n-        return super().get(request, *args, **kwargs)\n-\n-    def get_context_data(self, **kwargs):\n-        context = super().get_context_data(**kwargs)\n-        context[\"genre\"] = self.object\n-        return context\n-\n-    def get_queryset(self):\n-        display_unpublished = self.request.user.is_authenticated\n-        search_term = self.request.GET.get(\"incipit\")\n-        if not search_term:\n-            return self.get_genre_cantus_ids(display_unpublished=display_unpublished)\n-        else:\n-            search_term = search_term.strip(\" \")\n-            filtered_chants = [\n-                chant\n-                for chant in self.get_genre_cantus_ids(display_unpublished=display_unpublished)\n-                if search_term.lower() in chant[\"first_incipit\"].lower()\n-            ]\n-            return filtered_chants\n-\n \n class GenreListView(SearchableListMixin, ListView):\n     model = Genre\n", "issue": "Certain Genre Detail pages are _very_ slow to load\nI think the problem is trying to display the \"chants by genre\" table - for a genre with lots of example chants, e.g. [Antiphon](http://206.12.88.113/genre/122), I've tried loading the page several times and keep getting a 502 error.\n", "before_files": [{"content": "from typing import Dict, List\n\nfrom django.views.generic import ListView\nfrom django.views.generic.detail import SingleObjectMixin\nfrom extra_views import SearchableListMixin\nfrom main_app.models import Genre\n\n\nclass GenreDetailView(SingleObjectMixin, ListView):\n    paginate_by = 100\n    template_name = \"genre_detail.html\"\n\n    def get_genre_cantus_ids(self, display_unpublished=True) -> List[Dict]:\n        \"\"\"\n        Get a list with data on each unique ``cantus_id`` related to this Genre.\n\n        The list contains dicts and each dict has the following keys:\n\n        ``cantus_id``: The ``cantus_id``\n        ``num_chants``: The number of Chants that have this ``cantus_id``\n        ``first_incipit``: The incipit of first Chant with this ``cantus_id``\n        ``first_incipit_url``: The url of first Chant with this ``cantus_id``\n\n        Returns:\n            List[Dict]: A list of dicts with data on each unique ``cantus_id``\n        \"\"\"\n        cantus_ids = (self.object.chant_set\n            .exclude(cantus_id=None)\n            .values_list(\"cantus_id\", flat=True)\n            .distinct(\"cantus_id\")\n        )\n        if not display_unpublished:\n            cantus_ids = cantus_ids.filter(source__published=True)\n        \n        cantus_ids_list = list(cantus_ids)\n\n        chant_list = []\n        for cantus_id in cantus_ids_list:\n            chants = self.object.chant_set.filter(cantus_id=cantus_id)\n            num_chants = chants.count()\n            first_chant = chants.first()\n            first_incipit_url = first_chant.get_absolute_url()\n            first_incipit = first_chant.incipit\n            chant_list.append(\n                {\n                    \"cantus_id\": cantus_id,\n                    \"num_chants\": num_chants,\n                    \"first_incipit\": first_incipit,\n                    \"first_incipit_url\": first_incipit_url,\n                }\n            )\n        # Sort list based on number of Chants per cantus_id (descending)\n        chant_list = sorted(chant_list, key=lambda k: k[\"num_chants\"], reverse=True)\n        return chant_list\n\n    def get(self, request, *args, **kwargs):\n        self.object = self.get_object(queryset=Genre.objects.all())\n        return super().get(request, *args, **kwargs)\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n        context[\"genre\"] = self.object\n        return context\n\n    def get_queryset(self):\n        display_unpublished = self.request.user.is_authenticated\n        search_term = self.request.GET.get(\"incipit\")\n        if not search_term:\n            return self.get_genre_cantus_ids(display_unpublished=display_unpublished)\n        else:\n            search_term = search_term.strip(\" \")\n            filtered_chants = [\n                chant\n                for chant in self.get_genre_cantus_ids(display_unpublished=display_unpublished)\n                if search_term.lower() in chant[\"first_incipit\"].lower()\n            ]\n            return filtered_chants\n\n\nclass GenreListView(SearchableListMixin, ListView):\n    model = Genre\n    paginate_by = 100\n    context_object_name = \"genres\"\n    template_name = \"genre_list.html\"\n\n    def get_queryset(self):\n        queryset = super().get_queryset()\n        mass_office = self.request.GET.get(\"mass_office\", None)\n        if mass_office in [\"Mass\", \"Office\", \"Old Hispanic\"]:\n            queryset = queryset.filter(mass_office__contains=mass_office)\n        return queryset.order_by(\"name\")\n", "path": "django/cantusdb_project/main_app/views/genre.py"}], "after_files": [{"content": "from django.views.generic import DetailView, ListView\nfrom extra_views import SearchableListMixin\nfrom main_app.models import Genre\n\n\nclass GenreDetailView(DetailView):\n    model = Genre\n    context_object_name = \"genre\"\n    template_name = \"genre_detail.html\"\n\n\nclass GenreListView(SearchableListMixin, ListView):\n    model = Genre\n    paginate_by = 100\n    context_object_name = \"genres\"\n    template_name = \"genre_list.html\"\n\n    def get_queryset(self):\n        queryset = super().get_queryset()\n        mass_office = self.request.GET.get(\"mass_office\", None)\n        if mass_office in [\"Mass\", \"Office\", \"Old Hispanic\"]:\n            queryset = queryset.filter(mass_office__contains=mass_office)\n        return queryset.order_by(\"name\")\n", "path": "django/cantusdb_project/main_app/views/genre.py"}]}