Skip to content

Errata backend#5249

Open
gamboz wants to merge 5 commits into
openlibhums:masterfrom
sissamedialab:discussion-5238__errata-backend
Open

Errata backend#5249
gamboz wants to merge 5 commits into
openlibhums:masterfrom
sissamedialab:discussion-5238__errata-backend

Conversation

@gamboz

@gamboz gamboz commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator

Add the possibility of linking an erratum to an article and register this relation with Crossref.

See also discussion 5238

  • add Genealogy model to link Articles
  • add crossmark/updates section to crossref xml deposit for errata

ATM, errata are so rare that no front-end or manager interface is changed here, but an "admin" is provided.

Please note the new dependency.

@gamboz gamboz force-pushed the discussion-5238__errata-backend branch 2 times, most recently from a91fe97 to 21289b6 Compare March 30, 2026 15:15
@gamboz gamboz marked this pull request as draft April 17, 2026 07:17
@gamboz

gamboz commented Apr 17, 2026

Copy link
Copy Markdown
Collaborator Author

@mauromsl we have been notified of a small incoherence in the XML deposit specs (see https://github.com/orgs/openlibhums/discussions/5238#discussioncomment-16599730 ).

I've moved this MR to "draft".

I'll complete it after we publish our first erratum and ping again.

@gamboz gamboz force-pushed the discussion-5238__errata-backend branch from 21289b6 to ab30aa4 Compare April 27, 2026 11:32
@gamboz gamboz force-pushed the discussion-5238__errata-backend branch 3 times, most recently from 1047bef to 9c75895 Compare April 27, 2026 13:04
gamboz added 3 commits April 27, 2026 15:06
from crossref support staff:

> [...]
> You can't totally omit the <crossmark_policy> element. For historical reasons, it's strictly required by the schema. But, as a workaround, you can just repeat the DOI of the original paper in that field. It's not used for anything, but it has to have a valid DOI in it.
@gamboz gamboz force-pushed the discussion-5238__errata-backend branch from 9c75895 to 796c658 Compare April 27, 2026 13:11

{% if article.erratum_of %}
<crossmark>
<crossmark_policy>{{ article.object.journal|setting:'crossref_prefix' }}/not-used</crossmark_policy>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ according to XML specs, when recording an <update>, then a <crossmark_policy> DOI should also be provided, but, according to crossref support, that element is not used and any DOI would do. They suggested to use the article DOI, but I'm hardcoding a 10.11111/no-used fake DOI (I feel it's less confusing...)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mauromsl please feel free to resolve this thread if you have no objections

@gamboz

gamboz commented Apr 27, 2026

Copy link
Copy Markdown
Collaborator Author

@mauromsl we talked with @ajrbyers on Friday and after a couple of minor fixes I'm setting this as ready for review.

Note that there might be some issues with migrations that (I think) are not related to these changes.
Please let me know if you want me to point this to some other branch.

@gamboz gamboz marked this pull request as ready for review April 27, 2026 13:23
@mauromsl mauromsl self-requested a review April 28, 2026 11:27

@mauromsl mauromsl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @gamboz great work. I've proposed two main changes inline:

  • Avoid using the section names as the mechanism for serializing the relationship type of "errata"
  • Use a linker table with a through model relationship, ideally repurposing the model that already lives in the hydra plugin.

Comment thread src/submission/models.py
Comment on lines +2641 to +2644
if self.section.name != "Erratum":
return None
if not self.ancestors.exists():
return None

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it makes sense on the context of this PR, section.name is a customizable (and translatable) entry. Since we are adding a new model to register the relationships between articles, it would make sense to codify this (and other relationships) as part of that model, rather than relying on the indirection of the section name.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be addressed by openlibhums/Hydra#12

Comment thread src/submission/models.py
Comment on lines +3424 to +3445
class Genealogy(models.Model):
"""
Maintain relations of type parent/children between articles.

This can be used, for instance, to link erratum to the original paper.
"""

parent = models.OneToOneField(
Article,
verbose_name=_("Original or main paper"),
on_delete=models.CASCADE,
related_name="genealogy",
)
children = SortedManyToManyField(
Article,
related_name="ancestors",
)

def __str__(self):
return f"Genealogy: {self.parent} has {self.children.count()} kids"


Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the community are asking for a few more relationship types such as addendum, correction and so on. We also have a model on the hydra plugin for registering relationships such as translations.

Would it work for your use case if we were to port the LinkedArticle model from Hydra plugin instead?

It behaves as a linking table, so there is one less join required when querying both sides of the relationship.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be addressed by openlibhums/Hydra#12

Comment thread requirements.txt
pytz==2024.1
requests==2.32.4
six==1.16.0
django-sortedm2m~=3.1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we go with the approach I proposed about registering a model that behaves as a linking table, we could also use our M2MOrderedThroughField. It would avoid the additional dependency and also maintain consistency with other ordered many to many relationships in the codebase.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be addressed by openlibhums/Hydra#12

@mauromsl mauromsl assigned gamboz and unassigned mauromsl Apr 29, 2026
@gamboz gamboz marked this pull request as draft June 19, 2026 12:32
@gamboz gamboz force-pushed the discussion-5238__errata-backend branch 4 times, most recently from 37cf503 to 8fc6bc8 Compare June 22, 2026 18:27
Comment thread src/submission/models.py Outdated
Comment on lines +2621 to +2667
def ancestors(self, link_type: str) -> QuerySet["Article"]:
"""
Return articles related to self, where self is the "to-article".

This can be used, for instance, to refer to corrections in self's landing page.
"""
return self._related(link_type=link_type, direction="ancestors")

def descendants(self, link_type: str) -> QuerySet["Article"]:
"""
Return articles related to self, where self is the "from-article".

This can be used, for instance, to refer to corrections in self's landing page.
"""
return self._related(link_type=link_type, direction="descendants")

def _related(self, link_type: str, direction: str) -> QuerySet["Article"]:
"""
Return articles related to self.

Direction:
- descendants -> where self is the "from-article"
- ancenstors -> where self. is the "to-article"
"""
if not link_type:
return Article.objects.none()

# Silently return nothing if Hydra plugin is not available
try:
from plugins.hydra.models import LinkedArticle # noqa: F401
except ImportError:
return Article.objects.none()

if direction == "descendants":
# self is the "from-article"; return the "to-articles"
return Article.objects.filter(
linked_to__from_article=self, linked_to__relationship=link_type
)
if direction == "ancestors":
# self is the "to-article"; return the "from-articles"
return Article.objects.filter(
linked_from__to_article=self, linked_from__relationship=link_type
)

raise ValueError(
f"Unknown relationship direction '{direction}' requested for {self.id}"
)

@gamboz gamboz Jun 22, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote these methods as helpers for the theme templates, but before seeing that there was the sidebar_article_links hook in hydra.

ATM, these are not used and probably not necessary.

Let me know if you prefer I drop them 🙂

Please also see commit 3dc9f69 in Hydra

@gamboz gamboz marked this pull request as ready for review June 22, 2026 19:10
@gamboz gamboz requested a review from mauromsl June 23, 2026 07:27
@gamboz gamboz force-pushed the discussion-5238__errata-backend branch from 8fc6bc8 to 796c658 Compare June 24, 2026 18:24
@gamboz

gamboz commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator Author

@mauromsl something funny happened to this MR: I don't see my recent commits and the changes are still the old ones...

Please ignore this MR until I understand what's going on 😢

@gamboz gamboz marked this pull request as draft June 26, 2026 08:48
@gamboz gamboz force-pushed the discussion-5238__errata-backend branch from 796c658 to e64c22e Compare June 26, 2026 17:30
@gamboz

gamboz commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator Author

@mauromsl something funny happened to this MR: I don't see my recent commits and the changes are still the old ones...

Please ignore this MR until I understand what's going on 😢

Situation back to normal... (was github unhappy with me? I will worry about this on the beach all next week 🏖️ 🥳 )

@gamboz gamboz marked this pull request as ready for review June 26, 2026 17:39
@gamboz gamboz force-pushed the discussion-5238__errata-backend branch from e64c22e to 796c658 Compare July 2, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants