Skip to content

Commit

Permalink
Merge pull request #1473 from dchiller/add-bd-fields
Browse files Browse the repository at this point in the history
Update Chant model and related forms for Benedicamus Domino-specific fields
  • Loading branch information
dchiller authored May 23, 2024
2 parents 00848ce + dd53bf9 commit c3775c6
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 55 deletions.
90 changes: 49 additions & 41 deletions django/cantusdb_project/main_app/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
Provenance,
Century,
Sequence,
Differentia,
)
from .widgets import (
TextInputWidget,
Expand All @@ -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):
"""
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand All @@ -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):
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
),
),
]
46 changes: 44 additions & 2 deletions django/cantusdb_project/main_app/models/base_chant.py
Original file line number Diff line number Diff line change
@@ -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):
"""
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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.
Expand All @@ -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})'
Loading

0 comments on commit c3775c6

Please sign in to comment.