diff --git a/physionet-django/console/forms.py b/physionet-django/console/forms.py index e1ec6393a4..943bd5c33f 100644 --- a/physionet-django/console/forms.py +++ b/physionet-django/console/forms.py @@ -632,7 +632,7 @@ class NewsForm(forms.ModelForm): class Meta: model = News - fields = ('slug', 'title', 'content', 'url', 'project', 'front_page_banner') + fields = ('slug', 'title', 'content', 'url', 'project', 'link_all_versions', 'front_page_banner') class FeaturedForm(forms.Form): diff --git a/physionet-django/notification/migrations/0010_news_link_all_versions.py b/physionet-django/notification/migrations/0010_news_link_all_versions.py new file mode 100644 index 0000000000..f79b721590 --- /dev/null +++ b/physionet-django/notification/migrations/0010_news_link_all_versions.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.10 on 2024-01-30 20:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("notification", "0009_alter_news_slug"), + ] + + operations = [ + migrations.AddField( + model_name="news", + name="link_all_versions", + field=models.BooleanField( + default=False, + help_text="Check this to link the news item to all versions of the selected project", + ), + ), + ] diff --git a/physionet-django/notification/models.py b/physionet-django/notification/models.py index 1cae1c82f1..5a2f88a0da 100644 --- a/physionet-django/notification/models.py +++ b/physionet-django/notification/models.py @@ -13,8 +13,17 @@ class News(models.Model): content = SafeHTMLField() publish_datetime = models.DateTimeField(auto_now_add=True) url = models.URLField(default='', blank=True) - project = models.ForeignKey('project.PublishedProject', null=True, blank=True, - on_delete=models.SET_NULL, related_name='news') + project = models.ForeignKey( + 'project.PublishedProject', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='news' + ) + link_all_versions = models.BooleanField( + default=False, + help_text='Check this to link the news item to all versions of the selected project' + ) guid = models.CharField(max_length=64, default=uuid.uuid4) front_page_banner = models.BooleanField(default=False) slug = models.SlugField(max_length=100, unique=True) diff --git a/physionet-django/project/modelcomponents/publishedproject.py b/physionet-django/project/modelcomponents/publishedproject.py index 7d112eb831..9b5d25a89d 100644 --- a/physionet-django/project/modelcomponents/publishedproject.py +++ b/physionet-django/project/modelcomponents/publishedproject.py @@ -8,6 +8,8 @@ from django.urls import reverse from django.utils import timezone from django.utils.text import slugify + +from notification.models import News from project.managers.publishedproject import PublishedProjectManager from project.modelcomponents.access import DataAccessRequest, DataAccessRequestReviewer, DUASignature from project.modelcomponents.fields import SafeHTMLField @@ -377,3 +379,19 @@ def embargo_active(self): return True else: return False + + def get_all_news(self): + """ + Return all news items associated with this project. If any news item has + 'link_all_versions' set to True, include those news too. + """ + # Fetch news items directly related to this PublishedProject + direct_news = self.news.all() + + # Fetch news items related to other PublishedProjects where the + # link_all_versions flag is set to True + linked_news = News.objects.filter( + project__core_project=self.core_project, + link_all_versions=True).exclude(project=self) + + return direct_news | linked_news diff --git a/physionet-django/project/views.py b/physionet-django/project/views.py index 3dc934ed0e..f66e803e7a 100644 --- a/physionet-django/project/views.py +++ b/physionet-django/project/views.py @@ -1863,7 +1863,7 @@ def published_project(request, project_slug, version, subdir=''): topics = project.topics.all() languages = project.programming_languages.all() contact = project.contact - news = project.news.all().order_by('-publish_datetime') + news = project.get_all_news().order_by('-publish_datetime') parent_projects = project.parent_projects.all() # derived_projects = project.derived_publishedprojects.all() data_access = DataAccess.objects.filter(project=project)