diff --git a/django/cantusdb_project/articles/templates/article_list.html b/django/cantusdb_project/articles/templates/article_list.html
index 2cee5c5da..29233a8d3 100644
--- a/django/cantusdb_project/articles/templates/article_list.html
+++ b/django/cantusdb_project/articles/templates/article_list.html
@@ -2,7 +2,7 @@
{% load helper_tags %} {# for recent_articles #}
{% block content %}
- What's New | Cantus Manuscript Database
+ What's New | Cantus Database
What's New
diff --git a/django/cantusdb_project/cantusdb/settings.py b/django/cantusdb_project/cantusdb/settings.py
index cf00986fc..db85f497e 100644
--- a/django/cantusdb_project/cantusdb/settings.py
+++ b/django/cantusdb_project/cantusdb/settings.py
@@ -197,6 +197,9 @@
"debug_toolbar.panels.redirects.RedirectsPanel",
"debug_toolbar.panels.profiling.ProfilingPanel",
},
+ "SHOW_TOOLBAR_CALLBACK": lambda request: (
+ False if request.headers.get("x-requested-with") == "XMLHttpRequest" else True
+ ),
}
INTERNAL_IPS = [
diff --git a/django/cantusdb_project/main_app/forms.py b/django/cantusdb_project/main_app/forms.py
index 74159fba8..100027609 100644
--- a/django/cantusdb_project/main_app/forms.py
+++ b/django/cantusdb_project/main_app/forms.py
@@ -12,7 +12,6 @@
Provenance,
Century,
Sequence,
- Differentia,
)
from .widgets import (
TextInputWidget,
@@ -32,26 +31,6 @@
# ModelForm allows to build a form directly from a model
# see https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/
-"""
-# 3 ways of doing it
-#1 worst, helptext in the model will be missing
-class CommetnForm(forms.Form):
- marginalia = forms.CharField(
- label="Marginalia", widget=forms.TextInput(), help_text="help"
- )
- url = forms.URLField()
- comment = forms.CharField()
-
- url.widget.attrs.update({'class': 'special'})
- comment.widget.attrs.update(size='40')
-#2
-class CommentForm(forms.ModelForm):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.fields['name'].widget.attrs.update({'class': 'special'})
- self.fields['comment'].widget.attrs.update(size='40')
-"""
-
class NameModelChoiceField(forms.ModelChoiceField):
"""
@@ -67,7 +46,16 @@ def label_from_instance(self, obj):
return obj.name
-# 3 best
+class SelectWidgetNameModelChoiceField(NameModelChoiceField):
+ """
+ This class inherits from NameModelChoiceField, but uses the
+ the custom SelectWidget defined in widgets.py as its widget
+ (for styling).
+ """
+
+ widget = SelectWidget()
+
+
class ChantCreateForm(forms.ModelForm):
class Meta:
model = Chant
@@ -95,8 +83,13 @@ class Meta:
"content_structure",
"indexing_notes",
"addendum",
- # Temporarily commented; see #1452
- # "segment",
+ "segment",
+ "liturgical_function",
+ "polyphony",
+ "cm_melody_id",
+ "incipit_of_refrain",
+ "later_addition",
+ "rubrics",
]
# the widgets dictionary is ignored for a model field with a non-empty
# choices attribute. In this case, you must override the form field to
@@ -125,6 +118,12 @@ class Meta:
"content_structure": TextInputWidget(),
"indexing_notes": TextAreaWidget(),
"addendum": TextInputWidget(),
+ "polyphony": SelectWidget(),
+ "liturgical_function": SelectWidget(),
+ "cm_melody_id": TextInputWidget(),
+ "incipit_of_refrain": TextInputWidget(),
+ "later_addition": TextInputWidget(),
+ "rubrics": TextInputWidget(),
}
folio = forms.CharField(
@@ -149,14 +148,13 @@ class Meta:
"Mass Alleluias. Punctuation is omitted.",
)
- # Temporarily commented; see #1452
- # segment = forms.ModelChoiceField(
- # queryset=Segment.objects.all().order_by("id"),
- # required=True,
- # initial=Segment.objects.get(id=4063), # Default to the "Cantus" segment
- # help_text="Select the Database segment that the chant belongs to. "
- # "In most cases, this will be the CANTUS segment.",
- # )
+ segment = SelectWidgetNameModelChoiceField(
+ queryset=Segment.objects.all().order_by("id"),
+ required=True,
+ initial=Segment.objects.get(id=4063), # Default to the "Cantus" segment
+ help_text="Select the Database segment that the chant belongs to. "
+ "In most cases, this will be the CANTUS segment.",
+ )
# automatically computed fields
# source and incipit are mandatory fields in model,
@@ -283,8 +281,13 @@ class Meta:
"manuscript_full_text_proofread",
"volpiano_proofread",
"proofread_by",
- # Temporarily commented; see #1452
- # "segment",
+ "segment",
+ "liturgical_function",
+ "polyphony",
+ "cm_melody_id",
+ "incipit_of_refrain",
+ "later_addition",
+ "rubrics",
]
widgets = {
# manuscript_full_text_std_spelling: defined below (required)
@@ -314,6 +317,12 @@ class Meta:
"proofread_by": autocomplete.ModelSelect2Multiple(
url="proofread-by-autocomplete"
),
+ "polyphony": SelectWidget(),
+ "liturgical_function": SelectWidget(),
+ "cm_melody_id": TextInputWidget(),
+ "incipit_of_refrain": TextInputWidget(),
+ "later_addition": TextInputWidget(),
+ "rubrics": TextInputWidget(),
}
manuscript_full_text_std_spelling = forms.CharField(
@@ -338,13 +347,12 @@ class Meta:
help_text="Each folio starts with '1'.",
)
- # Temporarily commented; see #1452
- # segment = forms.ModelChoiceField(
- # queryset=Segment.objects.all().order_by("id"),
- # required=True,
- # help_text="Select the Database segment that the chant belongs to. "
- # "In most cases, this will be the CANTUS segment.",
- # )
+ segment = SelectWidgetNameModelChoiceField(
+ queryset=Segment.objects.all().order_by("id"),
+ required=True,
+ help_text="Select the Database segment that the chant belongs to. "
+ "In most cases, this will be the CANTUS segment.",
+ )
class SourceEditForm(forms.ModelForm):
@@ -681,7 +689,7 @@ class Meta:
title = forms.CharField(
required=True,
widget=TextInputWidget,
- help_text="Full Manuscript Identification (City, Archive, Shelf-mark)",
+ help_text="Full Source Identification (City, Archive, Shelf-mark)",
)
title.widget.attrs.update({"style": "width: 610px;"})
diff --git a/django/cantusdb_project/main_app/migrations/0011_chant_cm_melody_id_chant_incipit_of_refrain_and_more.py b/django/cantusdb_project/main_app/migrations/0011_chant_cm_melody_id_chant_incipit_of_refrain_and_more.py
new file mode 100644
index 000000000..4e8128e2a
--- /dev/null
+++ b/django/cantusdb_project/main_app/migrations/0011_chant_cm_melody_id_chant_incipit_of_refrain_and_more.py
@@ -0,0 +1,123 @@
+# Generated by Django 4.2.11 on 2024-05-23 12:41
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("main_app", "0010_source_exists_on_cantus_ultimus"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="chant",
+ name="cm_melody_id",
+ field=models.CharField(
+ blank=True,
+ max_length=64,
+ null=True,
+ verbose_name="Corpus Monodicum Melody ID",
+ ),
+ ),
+ migrations.AddField(
+ model_name="chant",
+ name="incipit_of_refrain",
+ field=models.CharField(
+ blank=True,
+ max_length=255,
+ null=True,
+ verbose_name="Incipit of the Refrain",
+ ),
+ ),
+ migrations.AddField(
+ model_name="chant",
+ name="later_addition",
+ field=models.CharField(blank=True, max_length=255, null=True),
+ ),
+ migrations.AddField(
+ model_name="chant",
+ name="liturgical_function",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("BD", "Benedicamus Domino"),
+ ("P", "Processional"),
+ ("H", "Historiae"),
+ ("D", "Dramatic Element"),
+ ],
+ max_length=10,
+ null=True,
+ verbose_name="Function",
+ ),
+ ),
+ migrations.AddField(
+ model_name="chant",
+ name="polyphony",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("2v", "2-voice polyphony"),
+ ("3v", "3-voice polyphony"),
+ ("4v", "4-voice polyphony"),
+ ],
+ max_length=10,
+ null=True,
+ ),
+ ),
+ migrations.AddField(
+ model_name="sequence",
+ name="cm_melody_id",
+ field=models.CharField(
+ blank=True,
+ max_length=64,
+ null=True,
+ verbose_name="Corpus Monodicum Melody ID",
+ ),
+ ),
+ migrations.AddField(
+ model_name="sequence",
+ name="incipit_of_refrain",
+ field=models.CharField(
+ blank=True,
+ max_length=255,
+ null=True,
+ verbose_name="Incipit of the Refrain",
+ ),
+ ),
+ migrations.AddField(
+ model_name="sequence",
+ name="later_addition",
+ field=models.CharField(blank=True, max_length=255, null=True),
+ ),
+ migrations.AddField(
+ model_name="sequence",
+ name="liturgical_function",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("BD", "Benedicamus Domino"),
+ ("P", "Processional"),
+ ("H", "Historiae"),
+ ("D", "Dramatic Element"),
+ ],
+ max_length=10,
+ null=True,
+ verbose_name="Function",
+ ),
+ ),
+ migrations.AddField(
+ model_name="sequence",
+ name="polyphony",
+ field=models.CharField(
+ blank=True,
+ choices=[
+ ("2v", "2-voice polyphony"),
+ ("3v", "3-voice polyphony"),
+ ("4v", "4-voice polyphony"),
+ ],
+ max_length=10,
+ null=True,
+ ),
+ ),
+ ]
diff --git a/django/cantusdb_project/main_app/models/base_chant.py b/django/cantusdb_project/main_app/models/base_chant.py
index 2db086911..2419185e0 100644
--- a/django/cantusdb_project/main_app/models/base_chant.py
+++ b/django/cantusdb_project/main_app/models/base_chant.py
@@ -1,8 +1,9 @@
-from main_app.models import BaseModel
from django.db import models
from django.contrib.auth import get_user_model
from django.contrib.postgres.search import SearchVectorField
+from main_app.models import BaseModel
+
class BaseChant(BaseModel):
"""
@@ -59,6 +60,25 @@ class Meta:
"Office", on_delete=models.PROTECT, null=True, blank=True
)
position = models.CharField(max_length=63, null=True, blank=True)
+
+ BENEDICAMUS_DOMINO = "BD"
+ PROCESSIONAL = "P"
+ HISTORIAE = "H"
+ DRAMATIC_ELEMENT = "D"
+ LITURGICAL_FUNCTION_CHOICES = [
+ (BENEDICAMUS_DOMINO, "Benedicamus Domino"),
+ (PROCESSIONAL, "Processional"),
+ (HISTORIAE, "Historiae"),
+ (DRAMATIC_ELEMENT, "Dramatic Element"),
+ ]
+ liturgical_function = models.CharField(
+ blank=True,
+ null=True,
+ choices=LITURGICAL_FUNCTION_CHOICES,
+ max_length=10,
+ verbose_name="Function",
+ )
+
feast = models.ForeignKey("Feast", on_delete=models.PROTECT, null=True, blank=True)
mode = models.CharField(max_length=63, null=True, blank=True)
differentia = models.CharField(blank=True, null=True, max_length=63)
@@ -116,6 +136,18 @@ class Meta:
volpiano_notes = models.TextField(null=True, blank=True)
volpiano_intervals = models.TextField(null=True, blank=True)
+ P2V = "2v"
+ P3V = "3v"
+ P4V = "4v"
+ POLYPHONY_CHOICES = [
+ (P2V, "2-voice polyphony"),
+ (P3V, "3-voice polyphony"),
+ (P4V, "4-voice polyphony"),
+ ]
+ polyphony = models.CharField(
+ blank=True, null=True, choices=POLYPHONY_CHOICES, max_length=10
+ )
+
# NB: the cao_concordances field should not be used in public-facing views, as it contains data that may be out-of-date.
# For more information, see https://github.com/DDMAL/CantusDB/wiki/BaseChant-Model
cao_concordances = models.CharField(
@@ -156,6 +188,16 @@ class Meta:
# dact = models.CharField(blank=True, null=True, max_length=64)
# also a second differentia field
+ # The following fields are currently used for chants in the Benedicamus Domino
+ # segment
+ cm_melody_id = models.CharField(
+ blank=True, null=True, max_length=64, verbose_name="Corpus Monodicum Melody ID"
+ )
+ incipit_of_refrain = models.CharField(
+ blank=True, null=True, max_length=255, verbose_name="Incipit of the Refrain"
+ )
+ later_addition = models.CharField(blank=True, null=True, max_length=255)
+
def get_ci_url(self) -> str:
"""Construct the url to the entry in Cantus Index correponding to the chant.
@@ -171,4 +213,4 @@ def __str__(self):
elif self.manuscript_full_text:
split_text = self.manuscript_full_text.split()
incipit = " ".join(split_text[:4])
- return '"{incip}" ({id})'.format(incip=incipit, id=self.id)
+ return f'"{incipit}" ({self.id})'
diff --git a/django/cantusdb_project/main_app/models/source.py b/django/cantusdb_project/main_app/models/source.py
index 35c8e73b2..6d0efe68b 100644
--- a/django/cantusdb_project/main_app/models/source.py
+++ b/django/cantusdb_project/main_app/models/source.py
@@ -27,7 +27,7 @@ class Source(BaseModel):
title = models.CharField(
max_length=255,
- help_text="Full Manuscript Identification (City, Archive, Shelf-mark)",
+ help_text="Full Source Identification (City, Archive, Shelf-mark)",
)
# the siglum field as implemented on the old Cantus is composed of both the RISM siglum and the shelfmark
# it is a human-readable ID for a source
@@ -64,7 +64,7 @@ class Source(BaseModel):
blank=True,
null=True,
max_length=63,
- help_text='Date of the manuscript (e.g. "1200s", "1300-1350", etc.)',
+ help_text='Date of the source (e.g. "1200s", "1300-1350", etc.)',
)
century = models.ManyToManyField("Century", related_name="sources", blank=True)
notation = models.ManyToManyField("Notation", related_name="sources", blank=True)
diff --git a/django/cantusdb_project/main_app/templates/browse_chants.html b/django/cantusdb_project/main_app/templates/browse_chants.html
index 96a86fe1b..a768f9a78 100644
--- a/django/cantusdb_project/main_app/templates/browse_chants.html
+++ b/django/cantusdb_project/main_app/templates/browse_chants.html
@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block content %}
-Browse Chants | Cantus Manuscript Database
+Browse Chants | Cantus Database
diff --git a/django/cantusdb_project/main_app/templates/century_detail.html b/django/cantusdb_project/main_app/templates/century_detail.html
index 2cd2ca3d9..571d7f37b 100644
--- a/django/cantusdb_project/main_app/templates/century_detail.html
+++ b/django/cantusdb_project/main_app/templates/century_detail.html
@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block content %}
-{{ century.name }} | Cantus Manuscript Database
+{{ century.name }} | Cantus Database
-
-
+
+
+
+ {{ form.liturgical_function.label_tag }}
+ {{ form.liturgical_function }}
+
@@ -135,6 +139,11 @@ Create Chant
{{ form.extra.label_tag }}
{{ form.extra }}
+
+
+ {{ form.polyphony.label_tag }}
+ {{ form.polyphony }}
+
@@ -169,11 +178,42 @@ Create Chant
+
+
+
+
+
+
+ {{ form.cm_melody_id.label_tag }}
+ {{ form.cm_melody_id }}
+
+
+
+ {{ form.incipit_of_refrain.label_tag }}
+ {{ form.incipit_of_refrain }}
+
+
+
+
+
+
+
+ {{ form.later_addition.label_tag }}
+ {{ form.later_addition }}
+
+
+
+
+
+ {{ form.rubrics.label_tag }}
+ {{ form.rubrics }}
+
+
+
-
+
{{ form.manuscript_full_text_std_spelling }}
{{ form.manuscript_full_text_std_spelling.help_text }}
@@ -191,8 +231,8 @@ Create Chant
-
+
{{ form.manuscript_full_text }}
{{ form.manuscript_full_text.help_text }}
diff --git a/django/cantusdb_project/main_app/templates/chant_delete.html b/django/cantusdb_project/main_app/templates/chant_delete.html
index de8c12420..22389e24b 100644
--- a/django/cantusdb_project/main_app/templates/chant_delete.html
+++ b/django/cantusdb_project/main_app/templates/chant_delete.html
@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block content %}
-Delete Chant | Cantus Manuscript Database
+Delete Chant | Cantus Database
-
-
+
+
+
+ {{ form.liturgical_function.label_tag }}
+ {{ form.liturgical_function }}
+
@@ -121,6 +125,10 @@
{{ form.extra.label_tag }}
{{ form.extra }}
+
+ {{ form.polyphony.label_tag }}
+ {{ form.polyphony }}
+
@@ -149,6 +157,38 @@
{% endif %}
+
+
+
+
+
+ {{ form.cm_melody_id.label_tag }}
+ {{ form.cm_melody_id }}
+
+
+
+ {{ form.incipit_of_refrain.label_tag }}
+ {{ form.incipit_of_refrain }}
+
+
+
+
+
+
+
+ {{ form.later_addition.label_tag }}
+ {{ form.later_addition }}
+
+
+
+
+
+ {{ form.rubrics.label_tag }}
+ {{ form.rubrics }}
+
+
+
+
{% if suggested_fulltext %}
@@ -163,7 +203,7 @@
{{ form.manuscript_full_text_std_spelling }}
@@ -173,7 +213,7 @@
{{ form.manuscript_full_text_std_proofread }}
@@ -189,7 +229,7 @@
{{ form.manuscript_full_text }}
@@ -199,7 +239,7 @@
{{ form.manuscript_full_text_proofread }}
diff --git a/django/cantusdb_project/main_app/templates/chant_search.html b/django/cantusdb_project/main_app/templates/chant_search.html
index 53ddd0b63..34161ec27 100644
--- a/django/cantusdb_project/main_app/templates/chant_search.html
+++ b/django/cantusdb_project/main_app/templates/chant_search.html
@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block content %}
-Search Chants | Cantus Manuscript Database
+Search Chants | Cantus Database
@@ -179,15 +179,15 @@ Search Chants
Mode
{% endif %}
-
+
{% if order == "has_fulltext" %}
{% if sort == "desc" %}
- MsFt ▼
+ FT ▼
{% else %}
- MsFt ▲
+ FT ▲
{% endif %}
{% else %}
- MsFt
+ FT
{% endif %}
diff --git a/django/cantusdb_project/main_app/templates/chant_seq_by_cantus_id.html b/django/cantusdb_project/main_app/templates/chant_seq_by_cantus_id.html
index 1cc55055d..1c88efcb5 100644
--- a/django/cantusdb_project/main_app/templates/chant_seq_by_cantus_id.html
+++ b/django/cantusdb_project/main_app/templates/chant_seq_by_cantus_id.html
@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block content %}
-Chants by Cantus ID: {{ cantus_id }} | Cantus Manuscript Database
+Chants by Cantus ID: {{ cantus_id }} | Cantus Database
What's New
diff --git a/django/cantusdb_project/cantusdb/settings.py b/django/cantusdb_project/cantusdb/settings.py index cf00986fc..db85f497e 100644 --- a/django/cantusdb_project/cantusdb/settings.py +++ b/django/cantusdb_project/cantusdb/settings.py @@ -197,6 +197,9 @@ "debug_toolbar.panels.redirects.RedirectsPanel", "debug_toolbar.panels.profiling.ProfilingPanel", }, + "SHOW_TOOLBAR_CALLBACK": lambda request: ( + False if request.headers.get("x-requested-with") == "XMLHttpRequest" else True + ), } INTERNAL_IPS = [ diff --git a/django/cantusdb_project/main_app/forms.py b/django/cantusdb_project/main_app/forms.py index 74159fba8..100027609 100644 --- a/django/cantusdb_project/main_app/forms.py +++ b/django/cantusdb_project/main_app/forms.py @@ -12,7 +12,6 @@ Provenance, Century, Sequence, - Differentia, ) from .widgets import ( TextInputWidget, @@ -32,26 +31,6 @@ # ModelForm allows to build a form directly from a model # see https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ -""" -# 3 ways of doing it -#1 worst, helptext in the model will be missing -class CommetnForm(forms.Form): - marginalia = forms.CharField( - label="Marginalia", widget=forms.TextInput(), help_text="help" - ) - url = forms.URLField() - comment = forms.CharField() - - url.widget.attrs.update({'class': 'special'}) - comment.widget.attrs.update(size='40') -#2 -class CommentForm(forms.ModelForm): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields['name'].widget.attrs.update({'class': 'special'}) - self.fields['comment'].widget.attrs.update(size='40') -""" - class NameModelChoiceField(forms.ModelChoiceField): """ @@ -67,7 +46,16 @@ def label_from_instance(self, obj): return obj.name -# 3 best +class SelectWidgetNameModelChoiceField(NameModelChoiceField): + """ + This class inherits from NameModelChoiceField, but uses the + the custom SelectWidget defined in widgets.py as its widget + (for styling). + """ + + widget = SelectWidget() + + class ChantCreateForm(forms.ModelForm): class Meta: model = Chant @@ -95,8 +83,13 @@ class Meta: "content_structure", "indexing_notes", "addendum", - # Temporarily commented; see #1452 - # "segment", + "segment", + "liturgical_function", + "polyphony", + "cm_melody_id", + "incipit_of_refrain", + "later_addition", + "rubrics", ] # the widgets dictionary is ignored for a model field with a non-empty # choices attribute. In this case, you must override the form field to @@ -125,6 +118,12 @@ class Meta: "content_structure": TextInputWidget(), "indexing_notes": TextAreaWidget(), "addendum": TextInputWidget(), + "polyphony": SelectWidget(), + "liturgical_function": SelectWidget(), + "cm_melody_id": TextInputWidget(), + "incipit_of_refrain": TextInputWidget(), + "later_addition": TextInputWidget(), + "rubrics": TextInputWidget(), } folio = forms.CharField( @@ -149,14 +148,13 @@ class Meta: "Mass Alleluias. Punctuation is omitted.", ) - # Temporarily commented; see #1452 - # segment = forms.ModelChoiceField( - # queryset=Segment.objects.all().order_by("id"), - # required=True, - # initial=Segment.objects.get(id=4063), # Default to the "Cantus" segment - # help_text="Select the Database segment that the chant belongs to. " - # "In most cases, this will be the CANTUS segment.", - # ) + segment = SelectWidgetNameModelChoiceField( + queryset=Segment.objects.all().order_by("id"), + required=True, + initial=Segment.objects.get(id=4063), # Default to the "Cantus" segment + help_text="Select the Database segment that the chant belongs to. " + "In most cases, this will be the CANTUS segment.", + ) # automatically computed fields # source and incipit are mandatory fields in model, @@ -283,8 +281,13 @@ class Meta: "manuscript_full_text_proofread", "volpiano_proofread", "proofread_by", - # Temporarily commented; see #1452 - # "segment", + "segment", + "liturgical_function", + "polyphony", + "cm_melody_id", + "incipit_of_refrain", + "later_addition", + "rubrics", ] widgets = { # manuscript_full_text_std_spelling: defined below (required) @@ -314,6 +317,12 @@ class Meta: "proofread_by": autocomplete.ModelSelect2Multiple( url="proofread-by-autocomplete" ), + "polyphony": SelectWidget(), + "liturgical_function": SelectWidget(), + "cm_melody_id": TextInputWidget(), + "incipit_of_refrain": TextInputWidget(), + "later_addition": TextInputWidget(), + "rubrics": TextInputWidget(), } manuscript_full_text_std_spelling = forms.CharField( @@ -338,13 +347,12 @@ class Meta: help_text="Each folio starts with '1'.", ) - # Temporarily commented; see #1452 - # segment = forms.ModelChoiceField( - # queryset=Segment.objects.all().order_by("id"), - # required=True, - # help_text="Select the Database segment that the chant belongs to. " - # "In most cases, this will be the CANTUS segment.", - # ) + segment = SelectWidgetNameModelChoiceField( + queryset=Segment.objects.all().order_by("id"), + required=True, + help_text="Select the Database segment that the chant belongs to. " + "In most cases, this will be the CANTUS segment.", + ) class SourceEditForm(forms.ModelForm): @@ -681,7 +689,7 @@ class Meta: title = forms.CharField( required=True, widget=TextInputWidget, - help_text="Full Manuscript Identification (City, Archive, Shelf-mark)", + help_text="Full Source Identification (City, Archive, Shelf-mark)", ) title.widget.attrs.update({"style": "width: 610px;"}) diff --git a/django/cantusdb_project/main_app/migrations/0011_chant_cm_melody_id_chant_incipit_of_refrain_and_more.py b/django/cantusdb_project/main_app/migrations/0011_chant_cm_melody_id_chant_incipit_of_refrain_and_more.py new file mode 100644 index 000000000..4e8128e2a --- /dev/null +++ b/django/cantusdb_project/main_app/migrations/0011_chant_cm_melody_id_chant_incipit_of_refrain_and_more.py @@ -0,0 +1,123 @@ +# Generated by Django 4.2.11 on 2024-05-23 12:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("main_app", "0010_source_exists_on_cantus_ultimus"), + ] + + operations = [ + migrations.AddField( + model_name="chant", + name="cm_melody_id", + field=models.CharField( + blank=True, + max_length=64, + null=True, + verbose_name="Corpus Monodicum Melody ID", + ), + ), + migrations.AddField( + model_name="chant", + name="incipit_of_refrain", + field=models.CharField( + blank=True, + max_length=255, + null=True, + verbose_name="Incipit of the Refrain", + ), + ), + migrations.AddField( + model_name="chant", + name="later_addition", + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="chant", + name="liturgical_function", + field=models.CharField( + blank=True, + choices=[ + ("BD", "Benedicamus Domino"), + ("P", "Processional"), + ("H", "Historiae"), + ("D", "Dramatic Element"), + ], + max_length=10, + null=True, + verbose_name="Function", + ), + ), + migrations.AddField( + model_name="chant", + name="polyphony", + field=models.CharField( + blank=True, + choices=[ + ("2v", "2-voice polyphony"), + ("3v", "3-voice polyphony"), + ("4v", "4-voice polyphony"), + ], + max_length=10, + null=True, + ), + ), + migrations.AddField( + model_name="sequence", + name="cm_melody_id", + field=models.CharField( + blank=True, + max_length=64, + null=True, + verbose_name="Corpus Monodicum Melody ID", + ), + ), + migrations.AddField( + model_name="sequence", + name="incipit_of_refrain", + field=models.CharField( + blank=True, + max_length=255, + null=True, + verbose_name="Incipit of the Refrain", + ), + ), + migrations.AddField( + model_name="sequence", + name="later_addition", + field=models.CharField(blank=True, max_length=255, null=True), + ), + migrations.AddField( + model_name="sequence", + name="liturgical_function", + field=models.CharField( + blank=True, + choices=[ + ("BD", "Benedicamus Domino"), + ("P", "Processional"), + ("H", "Historiae"), + ("D", "Dramatic Element"), + ], + max_length=10, + null=True, + verbose_name="Function", + ), + ), + migrations.AddField( + model_name="sequence", + name="polyphony", + field=models.CharField( + blank=True, + choices=[ + ("2v", "2-voice polyphony"), + ("3v", "3-voice polyphony"), + ("4v", "4-voice polyphony"), + ], + max_length=10, + null=True, + ), + ), + ] diff --git a/django/cantusdb_project/main_app/models/base_chant.py b/django/cantusdb_project/main_app/models/base_chant.py index 2db086911..2419185e0 100644 --- a/django/cantusdb_project/main_app/models/base_chant.py +++ b/django/cantusdb_project/main_app/models/base_chant.py @@ -1,8 +1,9 @@ -from main_app.models import BaseModel from django.db import models from django.contrib.auth import get_user_model from django.contrib.postgres.search import SearchVectorField +from main_app.models import BaseModel + class BaseChant(BaseModel): """ @@ -59,6 +60,25 @@ class Meta: "Office", on_delete=models.PROTECT, null=True, blank=True ) position = models.CharField(max_length=63, null=True, blank=True) + + BENEDICAMUS_DOMINO = "BD" + PROCESSIONAL = "P" + HISTORIAE = "H" + DRAMATIC_ELEMENT = "D" + LITURGICAL_FUNCTION_CHOICES = [ + (BENEDICAMUS_DOMINO, "Benedicamus Domino"), + (PROCESSIONAL, "Processional"), + (HISTORIAE, "Historiae"), + (DRAMATIC_ELEMENT, "Dramatic Element"), + ] + liturgical_function = models.CharField( + blank=True, + null=True, + choices=LITURGICAL_FUNCTION_CHOICES, + max_length=10, + verbose_name="Function", + ) + feast = models.ForeignKey("Feast", on_delete=models.PROTECT, null=True, blank=True) mode = models.CharField(max_length=63, null=True, blank=True) differentia = models.CharField(blank=True, null=True, max_length=63) @@ -116,6 +136,18 @@ class Meta: volpiano_notes = models.TextField(null=True, blank=True) volpiano_intervals = models.TextField(null=True, blank=True) + P2V = "2v" + P3V = "3v" + P4V = "4v" + POLYPHONY_CHOICES = [ + (P2V, "2-voice polyphony"), + (P3V, "3-voice polyphony"), + (P4V, "4-voice polyphony"), + ] + polyphony = models.CharField( + blank=True, null=True, choices=POLYPHONY_CHOICES, max_length=10 + ) + # NB: the cao_concordances field should not be used in public-facing views, as it contains data that may be out-of-date. # For more information, see https://github.com/DDMAL/CantusDB/wiki/BaseChant-Model cao_concordances = models.CharField( @@ -156,6 +188,16 @@ class Meta: # dact = models.CharField(blank=True, null=True, max_length=64) # also a second differentia field + # The following fields are currently used for chants in the Benedicamus Domino + # segment + cm_melody_id = models.CharField( + blank=True, null=True, max_length=64, verbose_name="Corpus Monodicum Melody ID" + ) + incipit_of_refrain = models.CharField( + blank=True, null=True, max_length=255, verbose_name="Incipit of the Refrain" + ) + later_addition = models.CharField(blank=True, null=True, max_length=255) + def get_ci_url(self) -> str: """Construct the url to the entry in Cantus Index correponding to the chant. @@ -171,4 +213,4 @@ def __str__(self): elif self.manuscript_full_text: split_text = self.manuscript_full_text.split() incipit = " ".join(split_text[:4]) - return '"{incip}" ({id})'.format(incip=incipit, id=self.id) + return f'"{incipit}" ({self.id})' diff --git a/django/cantusdb_project/main_app/models/source.py b/django/cantusdb_project/main_app/models/source.py index 35c8e73b2..6d0efe68b 100644 --- a/django/cantusdb_project/main_app/models/source.py +++ b/django/cantusdb_project/main_app/models/source.py @@ -27,7 +27,7 @@ class Source(BaseModel): title = models.CharField( max_length=255, - help_text="Full Manuscript Identification (City, Archive, Shelf-mark)", + help_text="Full Source Identification (City, Archive, Shelf-mark)", ) # the siglum field as implemented on the old Cantus is composed of both the RISM siglum and the shelfmark # it is a human-readable ID for a source @@ -64,7 +64,7 @@ class Source(BaseModel): blank=True, null=True, max_length=63, - help_text='Date of the manuscript (e.g. "1200s", "1300-1350", etc.)', + help_text='Date of the source (e.g. "1200s", "1300-1350", etc.)', ) century = models.ManyToManyField("Century", related_name="sources", blank=True) notation = models.ManyToManyField("Notation", related_name="sources", blank=True) diff --git a/django/cantusdb_project/main_app/templates/browse_chants.html b/django/cantusdb_project/main_app/templates/browse_chants.html index 96a86fe1b..a768f9a78 100644 --- a/django/cantusdb_project/main_app/templates/browse_chants.html +++ b/django/cantusdb_project/main_app/templates/browse_chants.html @@ -1,6 +1,6 @@ {% extends "base.html" %} {% block content %} -Create Chant
{{ form.extra.label_tag }} {{ form.extra }}Create Chant
{{ form.manuscript_full_text_std_spelling.help_text }}
@@ -191,8 +231,8 @@
{{ form.manuscript_full_text.help_text }}
diff --git a/django/cantusdb_project/main_app/templates/chant_delete.html b/django/cantusdb_project/main_app/templates/chant_delete.html
index de8c12420..22389e24b 100644
--- a/django/cantusdb_project/main_app/templates/chant_delete.html
+++ b/django/cantusdb_project/main_app/templates/chant_delete.html
@@ -1,6 +1,6 @@
{% extends "base.html" %}
{% block content %}
-Create Chant