We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
"my sources"" page side panel
http://206.12.88.113/my-sources/ has a "created by" side panel. This is
1. not paginated
3. includes all the sources and not just the created ones (so it's both extra- long and also redundant).
Staging:
<img width="1106" alt="image" src="https://github.com/DDMAL/CantusDB/assets/67451875/3d11789e-6027-4358-8595-328e95e89d7b">
on production this only has the sources created on production, so it only has one source (I'm assuming the others will show up once we sort out the "Created by" info from OldCantus?
<img width="1160" alt="image" src="https://github.com/DDMAL/CantusDB/assets/67451875/f6e98d78-0f66-421c-aad9-2ede47400d88">
On OldCantus it looks like this:

<img width="981" alt="image" src="https://github.com/DDMAL/CantusDB/assets/67451875/15f4b995-d930-4645-9ca4-3befce6a868d">



--- 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/user.py`
Content:
```
1 from django.urls import reverse
2 from django.db.models.aggregates import Count
3 from django.views.generic import DetailView
4 from django.contrib.auth import get_user_model, login as auth_login
5 from main_app.models import Source
6 from django.views.generic import ListView
7 from django.contrib.auth.mixins import LoginRequiredMixin
8 from django.db.models import Q
9 from django.core.paginator import Paginator
10 from django.contrib.auth.views import LogoutView, LoginView
11 from django.contrib import messages
12 from extra_views import SearchableListMixin
13 from django.http import HttpResponseRedirect
14 from django.core.exceptions import PermissionDenied
15 
16 
17 class UserDetailView(DetailView):
18     """Detail view for User model
19 
20     Accessed by /users/<pk>
21     """
22 
23     model = get_user_model()
24     context_object_name = "user"
25     template_name = "user_detail.html"
26 
27     def get_context_data(self, **kwargs):
28         user = self.get_object()
29         # to begin, if the person viewing the site is not logged in,
30         # they should only be able to view the detail pages of indexers,
31         # and not the detail pages of run-of-the-mill users
32         viewing_user = self.request.user
33         if not (viewing_user.is_authenticated or user.is_indexer):
34             raise PermissionDenied()
35 
36         context = super().get_context_data(**kwargs)
37         display_unpublished = viewing_user.is_authenticated
38         sort_by_siglum = lambda source: source.siglum
39         if display_unpublished:
40             context["inventoried_sources"] = sorted(
41                 user.inventoried_sources.all(), key=sort_by_siglum
42             )
43             context["full_text_sources"] = sorted(
44                 user.entered_full_text_for_sources.all(), key=sort_by_siglum
45             )
46             context["melody_sources"] = sorted(
47                 user.entered_melody_for_sources.all(), key=sort_by_siglum
48             )
49             context["proofread_sources"] = sorted(
50                 user.proofread_sources.all(), key=sort_by_siglum
51             )
52             context["edited_sources"] = sorted(
53                 user.edited_sources.all(), key=sort_by_siglum
54             )
55         else:
56             context["inventoried_sources"] = sorted(
57                 user.inventoried_sources.all().filter(published=True),
58                 key=sort_by_siglum,
59             )
60             context["full_text_sources"] = sorted(
61                 user.entered_full_text_for_sources.all().filter(published=True),
62                 key=sort_by_siglum,
63             )
64             context["melody_sources"] = sorted(
65                 user.entered_melody_for_sources.all().filter(published=True),
66                 key=sort_by_siglum,
67             )
68             context["proofread_sources"] = sorted(
69                 user.proofread_sources.all().filter(published=True), key=sort_by_siglum
70             )
71             context["edited_sources"] = sorted(
72                 user.edited_sources.all().filter(published=True), key=sort_by_siglum
73             )
74 
75         return context
76 
77 
78 class UserSourceListView(LoginRequiredMixin, ListView):
79     model = Source
80     context_object_name = "sources"
81     template_name = "user_source_list.html"
82     paginate_by = 100
83 
84     def get_queryset(self):
85         return (
86             Source.objects.filter(
87                 Q(current_editors=self.request.user)
88                 | Q(created_by=self.request.user)
89                 # | Q(inventoried_by=self.request.user)
90                 # | Q(full_text_entered_by=self.request.user)
91                 # | Q(melodies_entered_by=self.request.user)
92                 # | Q(proofreaders=self.request.user)
93                 # | Q(other_editors=self.request.user)
94             )
95             .order_by("-date_created")
96             .distinct()
97         )
98 
99     def get_context_data(self, **kwargs):
100         context = super().get_context_data(**kwargs)
101 
102         user_created_sources = (
103             Source.objects.filter(created_by=self.request.user)
104             .order_by("-date_created")
105             .distinct()
106         )
107         paginator = Paginator(user_created_sources, 10)
108         page_number = self.request.GET.get("page2")
109         page_obj = paginator.get_page(page_number)
110 
111         context["user_created_sources_page_obj"] = page_obj
112         return context
113 
114 
115 class CustomLogoutView(LogoutView):
116     def get_next_page(self):
117         next_page = super().get_next_page()
118         messages.success(self.request, "You have successfully logged out!")
119         return next_page
120 
121 
122 class UserListView(LoginRequiredMixin, SearchableListMixin, ListView):
123     """A list of all User objects
124 
125     This view is equivalent to the user list view on the old Cantus.
126     This includes all User objects on the old Cantus.
127     When passed a `?q=<query>` argument in the GET request, it will filter users
128     based on the fields defined in `search_fields` with the `icontains` lookup.
129 
130     Accessed by /users/
131     """
132 
133     model = get_user_model()
134     ordering = "full_name"
135     search_fields = ["full_name", "institution", "city", "country"]
136     paginate_by = 100
137     template_name = "user_list.html"
138     context_object_name = "users"
139 
140 
141 class IndexerListView(SearchableListMixin, ListView):
142     """A list of User objects shown to the public
143 
144     This view replaces the indexer list view on the old Cantus.
145     The indexers are considered a subset of all User objects, the subset shown to the public.
146     This includes the User objects corresponding to Indexer objects on the old Cantus.
147     When passed a `?q=<query>` argument in the GET request, it will filter users
148     based on the fields defined in `search_fields` with the `icontains` lookup.
149 
150     Accessed by /indexers/
151     """
152 
153     model = get_user_model()
154     ordering = "full_name"
155     search_fields = ["full_name", "institution", "city", "country"]
156     paginate_by = 100
157     template_name = "indexer_list.html"
158     context_object_name = "indexers"
159 
160     def get_queryset(self):
161         all_users = super().get_queryset()
162         indexers = all_users.filter(is_indexer=True)
163         display_unpublished = self.request.user.is_authenticated
164         if display_unpublished:
165             indexers = indexers.annotate(source_count=Count("inventoried_sources"))
166             # display those who have at least one source
167             return indexers.filter(source_count__gte=1)
168         else:
169             indexers = indexers.annotate(
170                 source_count=Count(
171                     "inventoried_sources", filter=Q(inventoried_sources__published=True)
172                 )
173             )
174             # display those who have at least one published source
175             return indexers.filter(source_count__gte=1)
176
```
--- 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/user.py b/django/cantusdb_project/main_app/views/user.py
--- a/django/cantusdb_project/main_app/views/user.py
+++ b/django/cantusdb_project/main_app/views/user.py
@@ -104,7 +104,7 @@
             .order_by("-date_created")
             .distinct()
         )
-        paginator = Paginator(user_created_sources, 10)
+        paginator = Paginator(user_created_sources, 6)
         page_number = self.request.GET.get("page2")
         page_obj = paginator.get_page(page_number)

{"golden_diff": "diff --git a/django/cantusdb_project/main_app/views/user.py b/django/cantusdb_project/main_app/views/user.py\n--- a/django/cantusdb_project/main_app/views/user.py\n+++ b/django/cantusdb_project/main_app/views/user.py\n@@ -104,7 +104,7 @@\n             .order_by(\"-date_created\")\n             .distinct()\n         )\n-        paginator = Paginator(user_created_sources, 10)\n+        paginator = Paginator(user_created_sources, 6)\n         page_number = self.request.GET.get(\"page2\")\n         page_obj = paginator.get_page(page_number)\n", "issue": "\"my sources\"\" page side panel\nhttp://206.12.88.113/my-sources/ has a \"created by\" side panel. This is\r\n1. not paginated\r\n3. includes all the sources and not just the created ones (so it's both extra- long and also redundant).\r\nStaging:\r\n<img width=\"1106\" alt=\"image\" src=\"https://github.com/DDMAL/CantusDB/assets/67451875/3d11789e-6027-4358-8595-328e95e89d7b\">\r\non production this only has the sources created on production, so it only has one source (I'm assuming the others will show up once we sort out the \"Created by\" info from OldCantus?\r\n<img width=\"1160\" alt=\"image\" src=\"https://github.com/DDMAL/CantusDB/assets/67451875/f6e98d78-0f66-421c-aad9-2ede47400d88\">\r\nOn OldCantus it looks like this:\r\n\r\n<img width=\"981\" alt=\"image\" src=\"https://github.com/DDMAL/CantusDB/assets/67451875/15f4b995-d930-4645-9ca4-3befce6a868d\">\r\n\r\n\n", "before_files": [{"content": "from django.urls import reverse\nfrom django.db.models.aggregates import Count\nfrom django.views.generic import DetailView\nfrom django.contrib.auth import get_user_model, login as auth_login\nfrom main_app.models import Source\nfrom django.views.generic import ListView\nfrom django.contrib.auth.mixins import LoginRequiredMixin\nfrom django.db.models import Q\nfrom django.core.paginator import Paginator\nfrom django.contrib.auth.views import LogoutView, LoginView\nfrom django.contrib import messages\nfrom extra_views import SearchableListMixin\nfrom django.http import HttpResponseRedirect\nfrom django.core.exceptions import PermissionDenied\n\n\nclass UserDetailView(DetailView):\n    \"\"\"Detail view for User model\n\n    Accessed by /users/<pk>\n    \"\"\"\n\n    model = get_user_model()\n    context_object_name = \"user\"\n    template_name = \"user_detail.html\"\n\n    def get_context_data(self, **kwargs):\n        user = self.get_object()\n        # to begin, if the person viewing the site is not logged in,\n        # they should only be able to view the detail pages of indexers,\n        # and not the detail pages of run-of-the-mill users\n        viewing_user = self.request.user\n        if not (viewing_user.is_authenticated or user.is_indexer):\n            raise PermissionDenied()\n\n        context = super().get_context_data(**kwargs)\n        display_unpublished = viewing_user.is_authenticated\n        sort_by_siglum = lambda source: source.siglum\n        if display_unpublished:\n            context[\"inventoried_sources\"] = sorted(\n                user.inventoried_sources.all(), key=sort_by_siglum\n            )\n            context[\"full_text_sources\"] = sorted(\n                user.entered_full_text_for_sources.all(), key=sort_by_siglum\n            )\n            context[\"melody_sources\"] = sorted(\n                user.entered_melody_for_sources.all(), key=sort_by_siglum\n            )\n            context[\"proofread_sources\"] = sorted(\n                user.proofread_sources.all(), key=sort_by_siglum\n            )\n            context[\"edited_sources\"] = sorted(\n                user.edited_sources.all(), key=sort_by_siglum\n            )\n        else:\n            context[\"inventoried_sources\"] = sorted(\n                user.inventoried_sources.all().filter(published=True),\n                key=sort_by_siglum,\n            )\n            context[\"full_text_sources\"] = sorted(\n                user.entered_full_text_for_sources.all().filter(published=True),\n                key=sort_by_siglum,\n            )\n            context[\"melody_sources\"] = sorted(\n                user.entered_melody_for_sources.all().filter(published=True),\n                key=sort_by_siglum,\n            )\n            context[\"proofread_sources\"] = sorted(\n                user.proofread_sources.all().filter(published=True), key=sort_by_siglum\n            )\n            context[\"edited_sources\"] = sorted(\n                user.edited_sources.all().filter(published=True), key=sort_by_siglum\n            )\n\n        return context\n\n\nclass UserSourceListView(LoginRequiredMixin, ListView):\n    model = Source\n    context_object_name = \"sources\"\n    template_name = \"user_source_list.html\"\n    paginate_by = 100\n\n    def get_queryset(self):\n        return (\n            Source.objects.filter(\n                Q(current_editors=self.request.user)\n                | Q(created_by=self.request.user)\n                # | Q(inventoried_by=self.request.user)\n                # | Q(full_text_entered_by=self.request.user)\n                # | Q(melodies_entered_by=self.request.user)\n                # | Q(proofreaders=self.request.user)\n                # | Q(other_editors=self.request.user)\n            )\n            .order_by(\"-date_created\")\n            .distinct()\n        )\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n\n        user_created_sources = (\n            Source.objects.filter(created_by=self.request.user)\n            .order_by(\"-date_created\")\n            .distinct()\n        )\n        paginator = Paginator(user_created_sources, 10)\n        page_number = self.request.GET.get(\"page2\")\n        page_obj = paginator.get_page(page_number)\n\n        context[\"user_created_sources_page_obj\"] = page_obj\n        return context\n\n\nclass CustomLogoutView(LogoutView):\n    def get_next_page(self):\n        next_page = super().get_next_page()\n        messages.success(self.request, \"You have successfully logged out!\")\n        return next_page\n\n\nclass UserListView(LoginRequiredMixin, SearchableListMixin, ListView):\n    \"\"\"A list of all User objects\n\n    This view is equivalent to the user list view on the old Cantus.\n    This includes all User objects on the old Cantus.\n    When passed a `?q=<query>` argument in the GET request, it will filter users\n    based on the fields defined in `search_fields` with the `icontains` lookup.\n\n    Accessed by /users/\n    \"\"\"\n\n    model = get_user_model()\n    ordering = \"full_name\"\n    search_fields = [\"full_name\", \"institution\", \"city\", \"country\"]\n    paginate_by = 100\n    template_name = \"user_list.html\"\n    context_object_name = \"users\"\n\n\nclass IndexerListView(SearchableListMixin, ListView):\n    \"\"\"A list of User objects shown to the public\n\n    This view replaces the indexer list view on the old Cantus.\n    The indexers are considered a subset of all User objects, the subset shown to the public.\n    This includes the User objects corresponding to Indexer objects on the old Cantus.\n    When passed a `?q=<query>` argument in the GET request, it will filter users\n    based on the fields defined in `search_fields` with the `icontains` lookup.\n\n    Accessed by /indexers/\n    \"\"\"\n\n    model = get_user_model()\n    ordering = \"full_name\"\n    search_fields = [\"full_name\", \"institution\", \"city\", \"country\"]\n    paginate_by = 100\n    template_name = \"indexer_list.html\"\n    context_object_name = \"indexers\"\n\n    def get_queryset(self):\n        all_users = super().get_queryset()\n        indexers = all_users.filter(is_indexer=True)\n        display_unpublished = self.request.user.is_authenticated\n        if display_unpublished:\n            indexers = indexers.annotate(source_count=Count(\"inventoried_sources\"))\n            # display those who have at least one source\n            return indexers.filter(source_count__gte=1)\n        else:\n            indexers = indexers.annotate(\n                source_count=Count(\n                    \"inventoried_sources\", filter=Q(inventoried_sources__published=True)\n                )\n            )\n            # display those who have at least one published source\n            return indexers.filter(source_count__gte=1)\n", "path": "django/cantusdb_project/main_app/views/user.py"}], "after_files": [{"content": "from django.urls import reverse\nfrom django.db.models.aggregates import Count\nfrom django.views.generic import DetailView\nfrom django.contrib.auth import get_user_model, login as auth_login\nfrom main_app.models import Source\nfrom django.views.generic import ListView\nfrom django.contrib.auth.mixins import LoginRequiredMixin\nfrom django.db.models import Q\nfrom django.core.paginator import Paginator\nfrom django.contrib.auth.views import LogoutView, LoginView\nfrom django.contrib import messages\nfrom extra_views import SearchableListMixin\nfrom django.http import HttpResponseRedirect\nfrom django.core.exceptions import PermissionDenied\n\n\nclass UserDetailView(DetailView):\n    \"\"\"Detail view for User model\n\n    Accessed by /users/<pk>\n    \"\"\"\n\n    model = get_user_model()\n    context_object_name = \"user\"\n    template_name = \"user_detail.html\"\n\n    def get_context_data(self, **kwargs):\n        user = self.get_object()\n        # to begin, if the person viewing the site is not logged in,\n        # they should only be able to view the detail pages of indexers,\n        # and not the detail pages of run-of-the-mill users\n        viewing_user = self.request.user\n        if not (viewing_user.is_authenticated or user.is_indexer):\n            raise PermissionDenied()\n\n        context = super().get_context_data(**kwargs)\n        display_unpublished = viewing_user.is_authenticated\n        sort_by_siglum = lambda source: source.siglum\n        if display_unpublished:\n            context[\"inventoried_sources\"] = sorted(\n                user.inventoried_sources.all(), key=sort_by_siglum\n            )\n            context[\"full_text_sources\"] = sorted(\n                user.entered_full_text_for_sources.all(), key=sort_by_siglum\n            )\n            context[\"melody_sources\"] = sorted(\n                user.entered_melody_for_sources.all(), key=sort_by_siglum\n            )\n            context[\"proofread_sources\"] = sorted(\n                user.proofread_sources.all(), key=sort_by_siglum\n            )\n            context[\"edited_sources\"] = sorted(\n                user.edited_sources.all(), key=sort_by_siglum\n            )\n        else:\n            context[\"inventoried_sources\"] = sorted(\n                user.inventoried_sources.all().filter(published=True),\n                key=sort_by_siglum,\n            )\n            context[\"full_text_sources\"] = sorted(\n                user.entered_full_text_for_sources.all().filter(published=True),\n                key=sort_by_siglum,\n            )\n            context[\"melody_sources\"] = sorted(\n                user.entered_melody_for_sources.all().filter(published=True),\n                key=sort_by_siglum,\n            )\n            context[\"proofread_sources\"] = sorted(\n                user.proofread_sources.all().filter(published=True), key=sort_by_siglum\n            )\n            context[\"edited_sources\"] = sorted(\n                user.edited_sources.all().filter(published=True), key=sort_by_siglum\n            )\n\n        return context\n\n\nclass UserSourceListView(LoginRequiredMixin, ListView):\n    model = Source\n    context_object_name = \"sources\"\n    template_name = \"user_source_list.html\"\n    paginate_by = 100\n\n    def get_queryset(self):\n        return (\n            Source.objects.filter(\n                Q(current_editors=self.request.user)\n                | Q(created_by=self.request.user)\n                # | Q(inventoried_by=self.request.user)\n                # | Q(full_text_entered_by=self.request.user)\n                # | Q(melodies_entered_by=self.request.user)\n                # | Q(proofreaders=self.request.user)\n                # | Q(other_editors=self.request.user)\n            )\n            .order_by(\"-date_created\")\n            .distinct()\n        )\n\n    def get_context_data(self, **kwargs):\n        context = super().get_context_data(**kwargs)\n\n        user_created_sources = (\n            Source.objects.filter(created_by=self.request.user)\n            .order_by(\"-date_created\")\n            .distinct()\n        )\n        paginator = Paginator(user_created_sources, 6)\n        page_number = self.request.GET.get(\"page2\")\n        page_obj = paginator.get_page(page_number)\n\n        context[\"user_created_sources_page_obj\"] = page_obj\n        return context\n\n\nclass CustomLogoutView(LogoutView):\n    def get_next_page(self):\n        next_page = super().get_next_page()\n        messages.success(self.request, \"You have successfully logged out!\")\n        return next_page\n\n\nclass UserListView(LoginRequiredMixin, SearchableListMixin, ListView):\n    \"\"\"A list of all User objects\n\n    This view is equivalent to the user list view on the old Cantus.\n    This includes all User objects on the old Cantus.\n    When passed a `?q=<query>` argument in the GET request, it will filter users\n    based on the fields defined in `search_fields` with the `icontains` lookup.\n\n    Accessed by /users/\n    \"\"\"\n\n    model = get_user_model()\n    ordering = \"full_name\"\n    search_fields = [\"full_name\", \"institution\", \"city\", \"country\"]\n    paginate_by = 100\n    template_name = \"user_list.html\"\n    context_object_name = \"users\"\n\n\nclass IndexerListView(SearchableListMixin, ListView):\n    \"\"\"A list of User objects shown to the public\n\n    This view replaces the indexer list view on the old Cantus.\n    The indexers are considered a subset of all User objects, the subset shown to the public.\n    This includes the User objects corresponding to Indexer objects on the old Cantus.\n    When passed a `?q=<query>` argument in the GET request, it will filter users\n    based on the fields defined in `search_fields` with the `icontains` lookup.\n\n    Accessed by /indexers/\n    \"\"\"\n\n    model = get_user_model()\n    ordering = \"full_name\"\n    search_fields = [\"full_name\", \"institution\", \"city\", \"country\"]\n    paginate_by = 100\n    template_name = \"indexer_list.html\"\n    context_object_name = \"indexers\"\n\n    def get_queryset(self):\n        all_users = super().get_queryset()\n        indexers = all_users.filter(is_indexer=True)\n        display_unpublished = self.request.user.is_authenticated\n        if display_unpublished:\n            indexers = indexers.annotate(source_count=Count(\"inventoried_sources\"))\n            # display those who have at least one source\n            return indexers.filter(source_count__gte=1)\n        else:\n            indexers = indexers.annotate(\n                source_count=Count(\n                    \"inventoried_sources\", filter=Q(inventoried_sources__published=True)\n                )\n            )\n            # display those who have at least one published source\n            return indexers.filter(source_count__gte=1)\n", "path": "django/cantusdb_project/main_app/views/user.py"}]}