We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
List of Genres: alphabetization should be case-insensitive
The Lists of Feasts (this includes the list of all feasts as well as only the temporale and only the sanctorale) are ordered by alphabetic order of feast name, except that capital letters are currently taking precedence; a capital "Z" comes before a lowercase "a" and that muddles the system somewhat. Behold:

<img width="1119" alt="NewCantus temporale list" src="https://github.com/DDMAL/CantusDB/assets/83373378/2c4f7d2e-df3c-4a57-8c52-7acbfe96b099">

You can see that the alphabet thing is solid until Ad Processionem, after which the third letter becomes lowercase (Ad aquam benedictio) and the alphabet starts all over again. Maybe this is preferable, but OldCantus doesn't take capitalization into account, so I thought I'd mention it.

This is the same list on OldCantus, for reference: 

<img width="1158" alt="OldCantus temporale list" src="https://github.com/DDMAL/CantusDB/assets/83373378/598ba519-a37a-478b-884f-a1ff6b07ee34">


--- 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/feast.py`
Content:
```
1 from django.views.generic import DetailView, ListView
2 from main_app.models import Feast, Source
3 from extra_views import SearchableListMixin
4 
5 # this categorization is not finalized yet
6 # the feastcode on old cantus requires cleaning
7 # for now we just leave this categorization as it is
8 TEMP_PREFIX = [
9     "01",
10     "02",
11     "03",
12     "04",
13     "05",
14     "06",
15     "07",
16     "08",
17     "09",
18     "10",
19     "11",
20     "16",
21     "17",
22 ]
23 SANC_PREFIX = ["12", "13", "14", "15"]
24 
25 
26 class FeastDetailView(DetailView):
27     model = Feast
28     context_object_name = "feast"
29     template_name = "feast_detail.html"
30 
31     def get_context_data(self, **kwargs):
32         context = super().get_context_data(**kwargs)
33 
34         display_unpublished = self.request.user.is_authenticated
35 
36         chants_in_feast = self.get_object().chant_set
37         if not display_unpublished:
38             chants_in_feast = chants_in_feast.filter(source__published=True)
39 
40         cantus_ids = list(
41             chants_in_feast.values_list("cantus_id", flat=True).distinct()
42         )
43 
44         counts = []
45         incipits = []
46         genres = []
47 
48         for cantus_id in cantus_ids:
49             chants = chants_in_feast.filter(cantus_id=cantus_id)
50             count = chants.count()
51             incipit = chants.first().incipit
52             genre = chants.first().genre
53 
54             counts.append(count)
55             incipits.append(incipit)
56             genres.append(genre)
57 
58         zipped = zip(cantus_ids, incipits, genres, counts)
59         zipped = sorted(zipped, key=lambda t: t[3], reverse=True)
60         context["frequent_chants_zip"] = zipped
61 
62         source_ids = list(
63             chants_in_feast.values_list("source__id", flat=True).distinct()
64         )
65         sources = Source.objects.filter(id__in=source_ids)
66         counts = [chants_in_feast.filter(source=source).count() for source in sources]
67 
68         zipped = zip(sources, counts)
69         zipped = sorted(zipped, key=lambda t: t[1], reverse=True)
70         context["sources_zip"] = zipped
71 
72         return context
73 
74 
75 class FeastListView(SearchableListMixin, ListView):
76     """Searchable List view for Feast model
77 
78     Accessed by /feasts/
79 
80     When passed a ``?q=<query>`` argument in the GET request, it will filter feasts
81     based on the fields defined in ``search_fields`` with the ``icontains`` lookup
82 
83     The feasts can also be filtered by `date` (temp/sanc) and `month` and ordered by `sort_by`,
84     which are also passed as GET parameters
85     """
86 
87     model = Feast
88     search_fields = ["name", "description", "feast_code"]
89     paginate_by = 100
90     context_object_name = "feasts"
91     template_name = "feast_list.html"
92 
93     def get_ordering(self):
94         ordering = self.request.GET.get("sort_by")
95         # feasts can be ordered by name or feast_code,
96         # default to ordering by name if given anything else
97         if ordering not in ["name", "feast_code"]:
98             ordering = "name"
99         return ordering
100 
101     def get_queryset(self):
102         queryset = super().get_queryset()
103         date = self.request.GET.get("date")
104         month = self.request.GET.get("month")
105         # temp vs sanc categorization is not finalized yet,
106         # the feastcode needs to be updated by the cantus people
107         if date == "temp":
108             queryset = queryset.filter(prefix__in=TEMP_PREFIX)
109         elif date == "sanc":
110             queryset = queryset.filter(prefix__in=SANC_PREFIX)
111 
112         if month and (int(month)) in range(1, 13):
113             month = int(month)
114             queryset = queryset.filter(month=month)
115 
116         return queryset
117
```
--- 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/feast.py b/django/cantusdb_project/main_app/views/feast.py
--- a/django/cantusdb_project/main_app/views/feast.py
+++ b/django/cantusdb_project/main_app/views/feast.py
@@ -1,4 +1,5 @@
 from django.views.generic import DetailView, ListView
+from django.db.models.functions import Lower
 from main_app.models import Feast, Source
 from extra_views import SearchableListMixin
 
@@ -90,13 +91,14 @@
     context_object_name = "feasts"
     template_name = "feast_list.html"
 
-    def get_ordering(self):
+    def get_ordering(self) -> tuple:
         ordering = self.request.GET.get("sort_by")
         # feasts can be ordered by name or feast_code,
         # default to ordering by name if given anything else
         if ordering not in ["name", "feast_code"]:
             ordering = "name"
-        return ordering
+        # case insensitive ordering by name
+        return (Lower(ordering),) if ordering == "name" else (ordering,)
 
     def get_queryset(self):
         queryset = super().get_queryset()

{"golden_diff": "diff --git a/django/cantusdb_project/main_app/views/feast.py b/django/cantusdb_project/main_app/views/feast.py\n--- a/django/cantusdb_project/main_app/views/feast.py\n+++ b/django/cantusdb_project/main_app/views/feast.py\n@@ -1,4 +1,5 @@\n from django.views.generic import DetailView, ListView\n+from django.db.models.functions import Lower\n from main_app.models import Feast, Source\n from extra_views import SearchableListMixin\n \n@@ -90,13 +91,14 @@\n     context_object_name = \"feasts\"\n     template_name = \"feast_list.html\"\n \n-    def get_ordering(self):\n+    def get_ordering(self) -> tuple:\n         ordering = self.request.GET.get(\"sort_by\")\n         # feasts can be ordered by name or feast_code,\n         # default to ordering by name if given anything else\n         if ordering not in [\"name\", \"feast_code\"]:\n             ordering = \"name\"\n-        return ordering\n+        # case insensitive ordering by name\n+        return (Lower(ordering),) if ordering == \"name\" else (ordering,)\n \n     def get_queryset(self):\n         queryset = super().get_queryset()\n", "issue": "List of Genres: alphabetization should be case-insensitive\nThe Lists of Feasts (this includes the list of all feasts as well as only the temporale and only the sanctorale) are ordered by alphabetic order of feast name, except that capital letters are currently taking precedence; a capital \"Z\" comes before a lowercase \"a\" and that muddles the system somewhat. Behold:\r\n\r\n<img width=\"1119\" alt=\"NewCantus temporale list\" src=\"https://github.com/DDMAL/CantusDB/assets/83373378/2c4f7d2e-df3c-4a57-8c52-7acbfe96b099\">\r\n\r\nYou can see that the alphabet thing is solid until Ad Processionem, after which the third letter becomes lowercase (Ad aquam benedictio) and the alphabet starts all over again. Maybe this is preferable, but OldCantus doesn't take capitalization into account, so I thought I'd mention it.\r\n\r\nThis is the same list on OldCantus, for reference: \r\n\r\n<img width=\"1158\" alt=\"OldCantus temporale list\" src=\"https://github.com/DDMAL/CantusDB/assets/83373378/598ba519-a37a-478b-884f-a1ff6b07ee34\">\r\n\n", "before_files": [{"content": "from django.views.generic import DetailView, ListView\nfrom main_app.models import Feast, Source\nfrom extra_views import SearchableListMixin\n\n# this categorization is not finalized yet\n# the feastcode on old cantus requires cleaning\n# for now we just leave this categorization as it is\nTEMP_PREFIX = [\n    \"01\",\n    \"02\",\n    \"03\",\n    \"04\",\n    \"05\",\n    \"06\",\n    \"07\",\n    \"08\",\n    \"09\",\n    \"10\",\n    \"11\",\n    \"16\",\n    \"17\",\n]\nSANC_PREFIX = [\"12\", \"13\", \"14\", \"15\"]\n\n\nclass FeastDetailView(DetailView):\n    model = Feast\n    context_object_name = \"feast\"\n    template_name = \"feast_detail.html\"\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n\n        display_unpublished = self.request.user.is_authenticated\n\n        chants_in_feast = self.get_object().chant_set\n        if not display_unpublished:\n            chants_in_feast = chants_in_feast.filter(source__published=True)\n\n        cantus_ids = list(\n            chants_in_feast.values_list(\"cantus_id\", flat=True).distinct()\n        )\n\n        counts = []\n        incipits = []\n        genres = []\n\n        for cantus_id in cantus_ids:\n            chants = chants_in_feast.filter(cantus_id=cantus_id)\n            count = chants.count()\n            incipit = chants.first().incipit\n            genre = chants.first().genre\n\n            counts.append(count)\n            incipits.append(incipit)\n            genres.append(genre)\n\n        zipped = zip(cantus_ids, incipits, genres, counts)\n        zipped = sorted(zipped, key=lambda t: t[3], reverse=True)\n        context[\"frequent_chants_zip\"] = zipped\n\n        source_ids = list(\n            chants_in_feast.values_list(\"source__id\", flat=True).distinct()\n        )\n        sources = Source.objects.filter(id__in=source_ids)\n        counts = [chants_in_feast.filter(source=source).count() for source in sources]\n\n        zipped = zip(sources, counts)\n        zipped = sorted(zipped, key=lambda t: t[1], reverse=True)\n        context[\"sources_zip\"] = zipped\n\n        return context\n\n\nclass FeastListView(SearchableListMixin, ListView):\n    \"\"\"Searchable List view for Feast model\n\n    Accessed by /feasts/\n\n    When passed a ``?q=<query>`` argument in the GET request, it will filter feasts\n    based on the fields defined in ``search_fields`` with the ``icontains`` lookup\n\n    The feasts can also be filtered by `date` (temp/sanc) and `month` and ordered by `sort_by`,\n    which are also passed as GET parameters\n    \"\"\"\n\n    model = Feast\n    search_fields = [\"name\", \"description\", \"feast_code\"]\n    paginate_by = 100\n    context_object_name = \"feasts\"\n    template_name = \"feast_list.html\"\n\n    def get_ordering(self):\n        ordering = self.request.GET.get(\"sort_by\")\n        # feasts can be ordered by name or feast_code,\n        # default to ordering by name if given anything else\n        if ordering not in [\"name\", \"feast_code\"]:\n            ordering = \"name\"\n        return ordering\n\n    def get_queryset(self):\n        queryset = super().get_queryset()\n        date = self.request.GET.get(\"date\")\n        month = self.request.GET.get(\"month\")\n        # temp vs sanc categorization is not finalized yet,\n        # the feastcode needs to be updated by the cantus people\n        if date == \"temp\":\n            queryset = queryset.filter(prefix__in=TEMP_PREFIX)\n        elif date == \"sanc\":\n            queryset = queryset.filter(prefix__in=SANC_PREFIX)\n\n        if month and (int(month)) in range(1, 13):\n            month = int(month)\n            queryset = queryset.filter(month=month)\n\n        return queryset\n", "path": "django/cantusdb_project/main_app/views/feast.py"}], "after_files": [{"content": "from django.views.generic import DetailView, ListView\nfrom django.db.models.functions import Lower\nfrom main_app.models import Feast, Source\nfrom extra_views import SearchableListMixin\n\n# this categorization is not finalized yet\n# the feastcode on old cantus requires cleaning\n# for now we just leave this categorization as it is\nTEMP_PREFIX = [\n    \"01\",\n    \"02\",\n    \"03\",\n    \"04\",\n    \"05\",\n    \"06\",\n    \"07\",\n    \"08\",\n    \"09\",\n    \"10\",\n    \"11\",\n    \"16\",\n    \"17\",\n]\nSANC_PREFIX = [\"12\", \"13\", \"14\", \"15\"]\n\n\nclass FeastDetailView(DetailView):\n    model = Feast\n    context_object_name = \"feast\"\n    template_name = \"feast_detail.html\"\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n\n        display_unpublished = self.request.user.is_authenticated\n\n        chants_in_feast = self.get_object().chant_set\n        if not display_unpublished:\n            chants_in_feast = chants_in_feast.filter(source__published=True)\n\n        cantus_ids = list(\n            chants_in_feast.values_list(\"cantus_id\", flat=True).distinct()\n        )\n\n        counts = []\n        incipits = []\n        genres = []\n\n        for cantus_id in cantus_ids:\n            chants = chants_in_feast.filter(cantus_id=cantus_id)\n            count = chants.count()\n            incipit = chants.first().incipit\n            genre = chants.first().genre\n\n            counts.append(count)\n            incipits.append(incipit)\n            genres.append(genre)\n\n        zipped = zip(cantus_ids, incipits, genres, counts)\n        zipped = sorted(zipped, key=lambda t: t[3], reverse=True)\n        context[\"frequent_chants_zip\"] = zipped\n\n        source_ids = list(\n            chants_in_feast.values_list(\"source__id\", flat=True).distinct()\n        )\n        sources = Source.objects.filter(id__in=source_ids)\n        counts = [chants_in_feast.filter(source=source).count() for source in sources]\n\n        zipped = zip(sources, counts)\n        zipped = sorted(zipped, key=lambda t: t[1], reverse=True)\n        context[\"sources_zip\"] = zipped\n\n        return context\n\n\nclass FeastListView(SearchableListMixin, ListView):\n    \"\"\"Searchable List view for Feast model\n\n    Accessed by /feasts/\n\n    When passed a ``?q=<query>`` argument in the GET request, it will filter feasts\n    based on the fields defined in ``search_fields`` with the ``icontains`` lookup\n\n    The feasts can also be filtered by `date` (temp/sanc) and `month` and ordered by `sort_by`,\n    which are also passed as GET parameters\n    \"\"\"\n\n    model = Feast\n    search_fields = [\"name\", \"description\", \"feast_code\"]\n    paginate_by = 100\n    context_object_name = \"feasts\"\n    template_name = \"feast_list.html\"\n\n    def get_ordering(self) -> tuple:\n        ordering = self.request.GET.get(\"sort_by\")\n        # feasts can be ordered by name or feast_code,\n        # default to ordering by name if given anything else\n        if ordering not in [\"name\", \"feast_code\"]:\n            ordering = \"name\"\n        # case insensitive ordering by name\n        return (Lower(ordering),) if ordering == \"name\" else (ordering,)\n\n    def get_queryset(self):\n        queryset = super().get_queryset()\n        date = self.request.GET.get(\"date\")\n        month = self.request.GET.get(\"month\")\n        # temp vs sanc categorization is not finalized yet,\n        # the feastcode needs to be updated by the cantus people\n        if date == \"temp\":\n            queryset = queryset.filter(prefix__in=TEMP_PREFIX)\n        elif date == \"sanc\":\n            queryset = queryset.filter(prefix__in=SANC_PREFIX)\n\n        if month and (int(month)) in range(1, 13):\n            month = int(month)\n            queryset = queryset.filter(month=month)\n\n        return queryset\n", "path": "django/cantusdb_project/main_app/views/feast.py"}]}