Source code for fairdm.core.project.validators
"""Validators for the project app."""
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
#: The keys a DataCite funding reference may carry. No others are accepted.
FUNDING_REFERENCE_KEYS = frozenset(
{
"funderName",
"funderIdentifier",
"funderIdentifierType",
"awardNumber",
"awardTitle",
"awardURI",
}
)
#: DataCite's controlled set of funder identifier schemes.
FUNDER_IDENTIFIER_TYPES = ("ISNI", "GRID", "Crossref Funder ID", "ROR", "Other")
[docs]
def validate_funding(value):
"""Validate that a value is a list of DataCite funding references.
A project may carry several funding records, so the stored value must be
a list. Each member must be an object carrying only keys from
``FUNDING_REFERENCE_KEYS``, with ``funderName`` required and every other
key optional. A ``funderIdentifierType``, when present, must be one of
DataCite's identifier schemes.
Args:
value: The funding value to validate.
Raises:
ValidationError: The value is not a list of funding reference objects. The error code
is ``funding_not_list``, ``funding_unknown_key``, ``funding_missing_funder_name``,
``funding_invalid_type`` or ``funding_invalid_identifier_type``.
"""
if not isinstance(value, list):
raise ValidationError(
_("Funding must be a list of funding reference objects."),
code="funding_not_list",
)
for record in value:
if not isinstance(record, dict):
raise ValidationError(
_("Funding must be a list of funding reference objects."),
code="funding_not_list",
)
unknown_keys = set(record) - FUNDING_REFERENCE_KEYS
if unknown_keys:
raise ValidationError(
_(
"'%(keys)s' is not a recognised funding reference field. "
"Accepted fields are: %(accepted)s."
),
code="funding_unknown_key",
params={
"keys": ", ".join(sorted(unknown_keys)),
"accepted": ", ".join(sorted(FUNDING_REFERENCE_KEYS)),
},
)
funder_name = record.get("funderName")
if not isinstance(funder_name, str) or not funder_name:
raise ValidationError(
_("Every funding reference must name a funder."),
code="funding_missing_funder_name",
)
for key in FUNDING_REFERENCE_KEYS - {"funderName"}:
value_ = record.get(key)
if value_ is not None and not isinstance(value_, str):
raise ValidationError(
_("'%(key)s' must be given as a string."),
code="funding_invalid_type",
params={"key": key},
)
identifier_type = record.get("funderIdentifierType")
if identifier_type and identifier_type not in FUNDER_IDENTIFIER_TYPES:
raise ValidationError(
_(
"'%(value)s' is not a funder identifier scheme DataCite "
"defines. Accepted schemes are: %(schemes)s."
),
code="funding_invalid_identifier_type",
params={
"value": identifier_type,
"schemes": ", ".join(FUNDER_IDENTIFIER_TYPES),
},
)