Repository: DDMAL/CantusDB

Issue:
Created sources not showing up in "sources created by user"
I added a new source after logging in. However, when checking back on the my-sources page, I don't see that source in the "sources created by user" list to the right of the page. It is also not listed under "my sources". 
As I'm the one who created the source, I think it's reasonable to associate that source to me in some way. This needs to be implemented. 


Discussion:
- The original CantusDB does not have any sources listed under "sources created by user" either. Also, would it not be redundant to have the same list under both "my sources" and "sources created by user"?
- As for the second question: I believe to implement this, we would have to update the Source model to add a ForeignKey field that associates the source object with a user. Are you fine with me updating the model for this modification?
If you create a source on the old Cantus, does it show up under "sources created by user"? I think it should. It makes much more sense if the sources created by the user are actually listed under "sources created by user". I think we should implement it like this, regardless of what the old Cantus does. 

It is not redundant because they are not the same list. 
"My sources" should have the source that the user has any kind of `write` access to. This includes the sources they created, edited, or proofread. 
"Sources created by user" should only have the sources they created. 

To associate a source object with the user who created it, I suggest using the `inventoried_by` field. If this later turns out to be inaccurate, we'll change it then. 
The current `inventoried_by` field relates to the Indexer model. Should I update this field to relate to the User model?
Yes. Please do. Thanks
in case it helps:
In Old Cantus, what you create is added to "Sources created by User" automatically. It doesn't show up under "My sources" until your name is added under "Current editor" on the source page (note: this is *not* a required field.)  So, on the one hand, My Sources includes many sources the editor might have access to, but didn't personally create (a very common scenario); and on the other hand, "sources created by user" might include sources you created, but for some reason aren't editing. (To be honest, I don't know why the creator isn't an editor by default.) 
Images of what this list looks like for me in Old Cantus with a dummy source (note: I had to add myself as an editor separately).

![image](https://user-images.githubusercontent.com/67451875/171061510-5f1dd3d0-1e1e-4245-b868-352e599174f3.png)

![image](https://user-images.githubusercontent.com/67451875/171061595-cc05de5c-c3cf-4b79-a764-ce94e89019ae.png)

after adding myself under "editor": 
![image](https://user-images.githubusercontent.com/67451875/171061570-b14c5899-8049-4336-a225-af42f3581730.png)

Hey Anna. Thanks for this information. Very helpful!

>  It doesn't show up under "My sources" until your name is added under "Current editor" on the source page

Does a source show up under "My sources" when I'm not a "current editor" but a "proofreader"?

Related question: when a source is "inventoried by" a person, does it mean that person created that source?
Good questions, @jwang44 ! 
The roles of "inventoried by" and "proofreader" don't seem to be ones I can assign (or if I can, I've never learned how)--everybody I put in shows up as "editor". And although I am proofreading several things, I don't think I have the status of "proofreader" anywhere! However, everything to which I have been added as a secondary editor shows up under My Sources. 

A person can inventory a source without necessarily creating it. See below, where a team of people inventoried the source, but presumably only one person created it. 
![image](https://user-images.githubusercontent.com/67451875/171233422-a452c011-b26a-4362-8a2f-c38b13d0bb9c.png)
It's even possibly that somebody not listed created the source but then didn't inventory it. Basically, a source has a unique creator, which is internal information--who made this node?--but many possible editors, who have access under My Sources. The "inventoried by" and "proofreader" labels are basically external facing, so viewers know who did what, but are not (as far as I know) relevant to how one can interact with the website. 



Resolving patch:
diff --git a/django/cantusdb_project/main_app/models/source.py b/django/cantusdb_project/main_app/models/source.py
--- a/django/cantusdb_project/main_app/models/source.py
+++ b/django/cantusdb_project/main_app/models/source.py
@@ -66,9 +66,9 @@ class Source(BaseModel):
     )
     # TODO: Fill this field up with JSON info when I have access to the Users
     current_editors = models.ManyToManyField(get_user_model(), related_name="sources_edited")
-    # created_by = models.ForeignKey(
-    #     get_user_model(), related_name="sources_created", on_delete=models.PROTECT, blank=True, null=True
-    # )
+    created_by = models.ForeignKey(
+        get_user_model(), related_name="sources_created", on_delete=models.PROTECT, blank=True, null=True
+    )
     inventoried_by = models.ManyToManyField(
         "Indexer", related_name="sources_inventoried"
     )
diff --git a/django/cantusdb_project/main_app/views/source.py b/django/cantusdb_project/main_app/views/source.py
--- a/django/cantusdb_project/main_app/views/source.py
+++ b/django/cantusdb_project/main_app/views/source.py
@@ -5,6 +5,7 @@
 from django.contrib import messages
 from django.urls import reverse
 from django.contrib.auth.mixins import LoginRequiredMixin
+from django.http import HttpResponseRedirect
 
 class SourceDetailView(DetailView):
     model = Source
@@ -232,17 +233,19 @@ def get_success_url(self):
         return reverse("source-create")
 
     def form_valid(self, form):
-        if form.is_valid():
-            messages.success(
-                self.request,
-                "Source created successfully!",
-            )
-            return super().form_valid(form)
-        else:
-            return super().form_invalid(form)
+        source = form.save(commit=False)
+        source.created_by = self.request.user
+        source.save()
+        form.save_m2m()
+        messages.success(
+            self.request,
+            "Source created successfully!",
+        )
+        return HttpResponseRedirect(self.get_success_url())
 
 class SourceEditView(LoginRequiredMixin, UpdateView):
     template_name = "source_edit.html"
     model = Source
     form_class = SourceEditForm 
-    pk_url_kwarg = "source_id"
\ No newline at end of file
+    pk_url_kwarg = "source_id"
+
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
@@ -5,6 +5,7 @@
 from django.views.generic import ListView
 from django.contrib.auth.mixins import LoginRequiredMixin
 from django.db.models import Q
+from django.core.paginator import Paginator
 
 class UserDetailView(DetailView):
     """Detail view for User model
@@ -21,14 +22,26 @@ class UserSourceListView(LoginRequiredMixin, ListView):
     model = Source
     context_object_name = "sources"
     template_name = "user_source_list.html"
+    paginate_by = 20
 
     def get_queryset(self):
         return Source.objects.filter(
-            Q(current_editors=self.request.user) 
-            # |
-            # Q(inventoried_by=self.request.user) |
-            # Q(full_text_entered_by=self.request.user) |
-            # Q(melodies_entered_by=self.request.user) |
-            # Q(proofreaders=self.request.user) |
-            # Q(other_editors=self.request.user) 
+            Q(current_editors=self.request.user)
+            | Q(created_by=self.request.user)
+            # | Q(inventoried_by=self.request.user)
+            # | Q(full_text_entered_by=self.request.user)
+            # | Q(melodies_entered_by=self.request.user)
+            # | Q(proofreaders=self.request.user)
+            # | Q(other_editors=self.request.user) 
         ).order_by("title")
+        
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+
+        user_created_sources = Source.objects.filter(created_by=self.request.user)
+        paginator = Paginator(user_created_sources, 10)
+        page_number = self.request.GET.get('page2')
+        page_obj = paginator.get_page(page_number)
+
+        context["user_created_sources_page_obj"] = page_obj
+        return context
\ No newline at end of file


Test patch: