prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  required fields 
  On OldCantus, to create a source you need both a manuscript ID and a siglum (fields marked with asterisk) otherwise it won't create the source. 
  NewCantus has no asterisks on these fields, and was quite happy to let me make sources with no siglum (though it does tell me to fill out an ID field if I try to submit without it.)
  
  On the chant level, Folio and Sequence seem to be required fields (they are not on OldCantus!) but are not marked as such with asterisks, either. 
  
  --- 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/models/source.py`
  Content:
  ```
  1 from django.db import models
  2 from main_app.models import BaseModel, Segment
  3 from django.contrib.auth import get_user_model
  4 
  5 
  6 class Source(BaseModel):
  7     cursus_choices = [("Monastic", "Monastic"), ("Secular", "Secular")]
  8     source_status_choices = [
  9         (
  10             "Editing process (not all the fields have been proofread)",
  11             "Editing process (not all the fields have been proofread)",
  12         ),
  13         ("Published / Complete", "Published / Complete"),
  14         ("Published / Proofread pending", "Published / Proofread pending"),
  15         ("Unpublished / Editing process", "Unpublished / Editing process"),
  16         ("Unpublished / Indexing process", "Unpublished / Indexing process"),
  17         ("Unpublished / Proofread pending", "Unpublished / Proofread pending"),
  18         ("Unpublished / Proofreading process", "Unpublished / Proofreading process"),
  19         ("Unpublished / No indexing activity", "Unpublished / No indexing activity"),
  20     ]
  21 
  22     # The old Cantus uses two fields to jointly control the access to sources. 
  23     # Here in the new Cantus, we only use one field, and there are two levels: published and unpublished.
  24     # Published sources are available to the public. 
  25     # Unpublished sources are hidden from the list and cannot be accessed by URL until the user logs in.
  26     published = models.BooleanField(blank=False, null=False, default=False)
  27 
  28     title = models.CharField(
  29         max_length=255,
  30         help_text="Full Manuscript Identification (City, Archive, Shelf-mark)",
  31     )
  32     # the siglum field as implemented on the old Cantus is composed of both the RISM siglum and the shelfmark
  33     # it is a human-readable ID for a source
  34     siglum = models.CharField(
  35         max_length=63, 
  36         null=True, 
  37         blank=True,
  38         help_text="RISM-style siglum + Shelf-mark (e.g. GB-Ob 202).",
  39     )
  40     # the RISM siglum uniquely identifies a library or holding institution
  41     rism_siglum = models.ForeignKey(
  42         "RismSiglum", on_delete=models.PROTECT, null=True, blank=True,
  43     )
  44     provenance = models.ForeignKey(
  45         "Provenance",
  46         on_delete=models.PROTECT,
  47         help_text="If the origin is unknown, select a location where the source was "
  48         "used later in its lifetime and provide details in the "
  49         '"Provenance notes" field.',
  50         null=True,
  51         blank=True,
  52         related_name="sources",
  53     )
  54     provenance_notes = models.TextField(
  55         blank=True,
  56         null=True,
  57         help_text="More exact indication of the provenance (if necessary)",
  58     )
  59     full_source = models.BooleanField(blank=True, null=True)
  60     date = models.CharField(
  61         blank=True,
  62         null=True,
  63         max_length=63,
  64         help_text='Date of the manuscript (e.g. "1200s", "1300-1350", etc.)',
  65     )
  66     century = models.ManyToManyField("Century", related_name="sources", blank=True)
  67     notation = models.ManyToManyField("Notation", related_name="sources", blank=True)
  68     cursus = models.CharField(
  69         blank=True, null=True, choices=cursus_choices, max_length=63
  70     )
  71     current_editors = models.ManyToManyField(get_user_model(), related_name="sources_user_can_edit", blank=True)
  72     
  73     inventoried_by = models.ManyToManyField(
  74         get_user_model(), related_name="inventoried_sources", blank=True
  75     )
  76     full_text_entered_by = models.ManyToManyField(
  77         get_user_model(), related_name="entered_full_text_for_sources", blank=True
  78     )
  79     melodies_entered_by = models.ManyToManyField(
  80         get_user_model(), related_name="entered_melody_for_sources", blank=True
  81     )
  82     proofreaders = models.ManyToManyField(get_user_model(), related_name="proofread_sources", blank=True)
  83     other_editors = models.ManyToManyField(get_user_model(), related_name="edited_sources", blank=True)
  84     
  85 
  86     segment = models.ForeignKey(
  87         "Segment", on_delete=models.PROTECT, blank=True, null=True
  88     )
  89     source_status = models.CharField(blank=True, null=True, choices=source_status_choices, max_length=255)
  90     complete_inventory = models.BooleanField(blank=True, null=True)
  91     summary = models.TextField(blank=True, null=True)
  92     liturgical_occasions = models.TextField(blank=True, null=True)
  93     description = models.TextField(blank=True, null=True)
  94     selected_bibliography = models.TextField(blank=True, null=True)
  95     image_link = models.URLField(
  96         blank=True, 
  97         null=True,
  98         help_text='HTTP link to the image gallery of the source.',
  99     )
  100     indexing_notes = models.TextField(blank=True, null=True)
  101     indexing_date = models.TextField(blank=True, null=True)
  102     json_info = models.JSONField(blank=True, null=True)
  103     fragmentarium_id = models.CharField(max_length=15, blank=True, null=True)
  104     dact_id = models.CharField(max_length=15, blank=True, null=True)
  105 
  106     # number_of_chants and number_of_melodies are used for rendering the source-list page (perhaps among other places)
  107     # they are automatically recalculated in main_app.signals.update_source_chant_count and
  108     # main_app.signals.update_source_melody_count every time a chant or sequence is saved or deleted
  109     number_of_chants = models.IntegerField(blank=True, null=True)
  110     number_of_melodies = models.IntegerField(blank=True, null=True)
  111 
  112     def __str__(self):
  113         string = '[{s}] {t} ({i})'.format(s=self.rism_siglum, t=self.title, i=self.id)
  114         return string
  115 
  116     def save(self, *args, **kwargs):
  117         # when creating a source, assign it to "CANTUS Database" segment by default
  118         if not self.segment:
  119             cantus_db_segment = Segment.objects.get(name="CANTUS Database")
  120             self.segment = cantus_db_segment
  121         super().save(*args, **kwargs)
  122
  ```
  --- 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/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
  @@ -33,8 +33,8 @@
       # it is a human-readable ID for a source
       siglum = models.CharField(
           max_length=63, 
  -        null=True, 
  -        blank=True,
  +        null=False, 
  +        blank=False,
           help_text="RISM-style siglum + Shelf-mark (e.g. GB-Ob 202).",
       )
       # the RISM siglum uniquely identifies a library or holding institution
  
verification_info: {"golden_diff": "diff --git a/django/cantusdb_project/main_app/models/source.py b/django/cantusdb_project/main_app/models/source.py\n--- a/django/cantusdb_project/main_app/models/source.py\n+++ b/django/cantusdb_project/main_app/models/source.py\n@@ -33,8 +33,8 @@\n     # it is a human-readable ID for a source\n     siglum = models.CharField(\n         max_length=63, \n-        null=True, \n-        blank=True,\n+        null=False, \n+        blank=False,\n         help_text=\"RISM-style siglum + Shelf-mark (e.g. GB-Ob 202).\",\n     )\n     # the RISM siglum uniquely identifies a library or holding institution\n", "issue": "required fields \nOn OldCantus, to create a source you need both a manuscript ID and a siglum (fields marked with asterisk) otherwise it won't create the source. \r\nNewCantus has no asterisks on these fields, and was quite happy to let me make sources with no siglum (though it does tell me to fill out an ID field if I try to submit without it.)\r\n\r\nOn the chant level, Folio and Sequence seem to be required fields (they are not on OldCantus!) but are not marked as such with asterisks, either. \n", "before_files": [{"content": "from django.db import models\nfrom main_app.models import BaseModel, Segment\nfrom django.contrib.auth import get_user_model\n\n\nclass Source(BaseModel):\n    cursus_choices = [(\"Monastic\", \"Monastic\"), (\"Secular\", \"Secular\")]\n    source_status_choices = [\n        (\n            \"Editing process (not all the fields have been proofread)\",\n            \"Editing process (not all the fields have been proofread)\",\n        ),\n        (\"Published / Complete\", \"Published / Complete\"),\n        (\"Published / Proofread pending\", \"Published / Proofread pending\"),\n        (\"Unpublished / Editing process\", \"Unpublished / Editing process\"),\n        (\"Unpublished / Indexing process\", \"Unpublished / Indexing process\"),\n        (\"Unpublished / Proofread pending\", \"Unpublished / Proofread pending\"),\n        (\"Unpublished / Proofreading process\", \"Unpublished / Proofreading process\"),\n        (\"Unpublished / No indexing activity\", \"Unpublished / No indexing activity\"),\n    ]\n\n    # The old Cantus uses two fields to jointly control the access to sources. \n    # Here in the new Cantus, we only use one field, and there are two levels: published and unpublished.\n    # Published sources are available to the public. \n    # Unpublished sources are hidden from the list and cannot be accessed by URL until the user logs in.\n    published = models.BooleanField(blank=False, null=False, default=False)\n\n    title = models.CharField(\n        max_length=255,\n        help_text=\"Full Manuscript Identification (City, Archive, Shelf-mark)\",\n    )\n    # the siglum field as implemented on the old Cantus is composed of both the RISM siglum and the shelfmark\n    # it is a human-readable ID for a source\n    siglum = models.CharField(\n        max_length=63, \n        null=True, \n        blank=True,\n        help_text=\"RISM-style siglum + Shelf-mark (e.g. GB-Ob 202).\",\n    )\n    # the RISM siglum uniquely identifies a library or holding institution\n    rism_siglum = models.ForeignKey(\n        \"RismSiglum\", on_delete=models.PROTECT, null=True, blank=True,\n    )\n    provenance = models.ForeignKey(\n        \"Provenance\",\n        on_delete=models.PROTECT,\n        help_text=\"If the origin is unknown, select a location where the source was \"\n        \"used later in its lifetime and provide details in the \"\n        '\"Provenance notes\" field.',\n        null=True,\n        blank=True,\n        related_name=\"sources\",\n    )\n    provenance_notes = models.TextField(\n        blank=True,\n        null=True,\n        help_text=\"More exact indication of the provenance (if necessary)\",\n    )\n    full_source = models.BooleanField(blank=True, null=True)\n    date = models.CharField(\n        blank=True,\n        null=True,\n        max_length=63,\n        help_text='Date of the manuscript (e.g. \"1200s\", \"1300-1350\", etc.)',\n    )\n    century = models.ManyToManyField(\"Century\", related_name=\"sources\", blank=True)\n    notation = models.ManyToManyField(\"Notation\", related_name=\"sources\", blank=True)\n    cursus = models.CharField(\n        blank=True, null=True, choices=cursus_choices, max_length=63\n    )\n    current_editors = models.ManyToManyField(get_user_model(), related_name=\"sources_user_can_edit\", blank=True)\n    \n    inventoried_by = models.ManyToManyField(\n        get_user_model(), related_name=\"inventoried_sources\", blank=True\n    )\n    full_text_entered_by = models.ManyToManyField(\n        get_user_model(), related_name=\"entered_full_text_for_sources\", blank=True\n    )\n    melodies_entered_by = models.ManyToManyField(\n        get_user_model(), related_name=\"entered_melody_for_sources\", blank=True\n    )\n    proofreaders = models.ManyToManyField(get_user_model(), related_name=\"proofread_sources\", blank=True)\n    other_editors = models.ManyToManyField(get_user_model(), related_name=\"edited_sources\", blank=True)\n    \n\n    segment = models.ForeignKey(\n        \"Segment\", on_delete=models.PROTECT, blank=True, null=True\n    )\n    source_status = models.CharField(blank=True, null=True, choices=source_status_choices, max_length=255)\n    complete_inventory = models.BooleanField(blank=True, null=True)\n    summary = models.TextField(blank=True, null=True)\n    liturgical_occasions = models.TextField(blank=True, null=True)\n    description = models.TextField(blank=True, null=True)\n    selected_bibliography = models.TextField(blank=True, null=True)\n    image_link = models.URLField(\n        blank=True, \n        null=True,\n        help_text='HTTP link to the image gallery of the source.',\n    )\n    indexing_notes = models.TextField(blank=True, null=True)\n    indexing_date = models.TextField(blank=True, null=True)\n    json_info = models.JSONField(blank=True, null=True)\n    fragmentarium_id = models.CharField(max_length=15, blank=True, null=True)\n    dact_id = models.CharField(max_length=15, blank=True, null=True)\n\n    # number_of_chants and number_of_melodies are used for rendering the source-list page (perhaps among other places)\n    # they are automatically recalculated in main_app.signals.update_source_chant_count and\n    # main_app.signals.update_source_melody_count every time a chant or sequence is saved or deleted\n    number_of_chants = models.IntegerField(blank=True, null=True)\n    number_of_melodies = models.IntegerField(blank=True, null=True)\n\n    def __str__(self):\n        string = '[{s}] {t} ({i})'.format(s=self.rism_siglum, t=self.title, i=self.id)\n        return string\n\n    def save(self, *args, **kwargs):\n        # when creating a source, assign it to \"CANTUS Database\" segment by default\n        if not self.segment:\n            cantus_db_segment = Segment.objects.get(name=\"CANTUS Database\")\n            self.segment = cantus_db_segment\n        super().save(*args, **kwargs)\n", "path": "django/cantusdb_project/main_app/models/source.py"}], "after_files": [{"content": "from django.db import models\nfrom main_app.models import BaseModel, Segment\nfrom django.contrib.auth import get_user_model\n\n\nclass Source(BaseModel):\n    cursus_choices = [(\"Monastic\", \"Monastic\"), (\"Secular\", \"Secular\")]\n    source_status_choices = [\n        (\n            \"Editing process (not all the fields have been proofread)\",\n            \"Editing process (not all the fields have been proofread)\",\n        ),\n        (\"Published / Complete\", \"Published / Complete\"),\n        (\"Published / Proofread pending\", \"Published / Proofread pending\"),\n        (\"Unpublished / Editing process\", \"Unpublished / Editing process\"),\n        (\"Unpublished / Indexing process\", \"Unpublished / Indexing process\"),\n        (\"Unpublished / Proofread pending\", \"Unpublished / Proofread pending\"),\n        (\"Unpublished / Proofreading process\", \"Unpublished / Proofreading process\"),\n        (\"Unpublished / No indexing activity\", \"Unpublished / No indexing activity\"),\n    ]\n\n    # The old Cantus uses two fields to jointly control the access to sources. \n    # Here in the new Cantus, we only use one field, and there are two levels: published and unpublished.\n    # Published sources are available to the public. \n    # Unpublished sources are hidden from the list and cannot be accessed by URL until the user logs in.\n    published = models.BooleanField(blank=False, null=False, default=False)\n\n    title = models.CharField(\n        max_length=255,\n        help_text=\"Full Manuscript Identification (City, Archive, Shelf-mark)\",\n    )\n    # the siglum field as implemented on the old Cantus is composed of both the RISM siglum and the shelfmark\n    # it is a human-readable ID for a source\n    siglum = models.CharField(\n        max_length=63, \n        null=False, \n        blank=False,\n        help_text=\"RISM-style siglum + Shelf-mark (e.g. GB-Ob 202).\",\n    )\n    # the RISM siglum uniquely identifies a library or holding institution\n    rism_siglum = models.ForeignKey(\n        \"RismSiglum\", on_delete=models.PROTECT, null=True, blank=True,\n    )\n    provenance = models.ForeignKey(\n        \"Provenance\",\n        on_delete=models.PROTECT,\n        help_text=\"If the origin is unknown, select a location where the source was \"\n        \"used later in its lifetime and provide details in the \"\n        '\"Provenance notes\" field.',\n        null=True,\n        blank=True,\n        related_name=\"sources\",\n    )\n    provenance_notes = models.TextField(\n        blank=True,\n        null=True,\n        help_text=\"More exact indication of the provenance (if necessary)\",\n    )\n    full_source = models.BooleanField(blank=True, null=True)\n    date = models.CharField(\n        blank=True,\n        null=True,\n        max_length=63,\n        help_text='Date of the manuscript (e.g. \"1200s\", \"1300-1350\", etc.)',\n    )\n    century = models.ManyToManyField(\"Century\", related_name=\"sources\", blank=True)\n    notation = models.ManyToManyField(\"Notation\", related_name=\"sources\", blank=True)\n    cursus = models.CharField(\n        blank=True, null=True, choices=cursus_choices, max_length=63\n    )\n    current_editors = models.ManyToManyField(get_user_model(), related_name=\"sources_user_can_edit\", blank=True)\n    \n    inventoried_by = models.ManyToManyField(\n        get_user_model(), related_name=\"inventoried_sources\", blank=True\n    )\n    full_text_entered_by = models.ManyToManyField(\n        get_user_model(), related_name=\"entered_full_text_for_sources\", blank=True\n    )\n    melodies_entered_by = models.ManyToManyField(\n        get_user_model(), related_name=\"entered_melody_for_sources\", blank=True\n    )\n    proofreaders = models.ManyToManyField(get_user_model(), related_name=\"proofread_sources\", blank=True)\n    other_editors = models.ManyToManyField(get_user_model(), related_name=\"edited_sources\", blank=True)\n    \n\n    segment = models.ForeignKey(\n        \"Segment\", on_delete=models.PROTECT, blank=True, null=True\n    )\n    source_status = models.CharField(blank=True, null=True, choices=source_status_choices, max_length=255)\n    complete_inventory = models.BooleanField(blank=True, null=True)\n    summary = models.TextField(blank=True, null=True)\n    liturgical_occasions = models.TextField(blank=True, null=True)\n    description = models.TextField(blank=True, null=True)\n    selected_bibliography = models.TextField(blank=True, null=True)\n    image_link = models.URLField(\n        blank=True, \n        null=True,\n        help_text='HTTP link to the image gallery of the source.',\n    )\n    indexing_notes = models.TextField(blank=True, null=True)\n    indexing_date = models.TextField(blank=True, null=True)\n    json_info = models.JSONField(blank=True, null=True)\n    fragmentarium_id = models.CharField(max_length=15, blank=True, null=True)\n    dact_id = models.CharField(max_length=15, blank=True, null=True)\n\n    # number_of_chants and number_of_melodies are used for rendering the source-list page (perhaps among other places)\n    # they are automatically recalculated in main_app.signals.update_source_chant_count and\n    # main_app.signals.update_source_melody_count every time a chant or sequence is saved or deleted\n    number_of_chants = models.IntegerField(blank=True, null=True)\n    number_of_melodies = models.IntegerField(blank=True, null=True)\n\n    def __str__(self):\n        string = '[{s}] {t} ({i})'.format(s=self.rism_siglum, t=self.title, i=self.id)\n        return string\n\n    def save(self, *args, **kwargs):\n        # when creating a source, assign it to \"CANTUS Database\" segment by default\n        if not self.segment:\n            cantus_db_segment = Segment.objects.get(name=\"CANTUS Database\")\n            self.segment = cantus_db_segment\n        super().save(*args, **kwargs)\n", "path": "django/cantusdb_project/main_app/models/source.py"}]}