From bd1d5b6c6ca82b912c435564792e59dcacc3a994 Mon Sep 17 00:00:00 2001 From: James Biggs Date: Thu, 19 Dec 2024 16:53:05 +0000 Subject: [PATCH] Changed NewLabelMixin for PublishedDateMixin, to use published_date instead of newly_published_at --- etna/api/tests/test_pages.py | 2 +- ...epage_mark_new_on_next_publish_and_more.py | 65 +++++++++++++++ etna/articles/models.py | 47 ++++++----- ...emove_blogindexpage_hero_image_and_more.py | 31 +++++++ etna/blog/models.py | 37 ++++----- etna/collections/models.py | 4 +- etna/core/models/mixins.py | 81 +++++-------------- 7 files changed, 160 insertions(+), 107 deletions(-) create mode 100644 etna/articles/migrations/0113_remove_articlepage_mark_new_on_next_publish_and_more.py create mode 100644 etna/blog/migrations/0007_remove_blogindexpage_hero_image_and_more.py diff --git a/etna/api/tests/test_pages.py b/etna/api/tests/test_pages.py index 4e6fcc738..bccc953dc 100644 --- a/etna/api/tests/test_pages.py +++ b/etna/api/tests/test_pages.py @@ -146,7 +146,7 @@ def setUpTestData(cls): PageTimePeriod(time_period=cls.postwar), ], first_published_at=DATE_1, - newly_published_at=DATE_1, + published_date=DATE_1, mark_new_on_next_publish=False, ) diff --git a/etna/articles/migrations/0113_remove_articlepage_mark_new_on_next_publish_and_more.py b/etna/articles/migrations/0113_remove_articlepage_mark_new_on_next_publish_and_more.py new file mode 100644 index 000000000..7a444482e --- /dev/null +++ b/etna/articles/migrations/0113_remove_articlepage_mark_new_on_next_publish_and_more.py @@ -0,0 +1,65 @@ +# Generated by Django 5.1.2 on 2024-12-19 16:48 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("articles", "0112_alter_articlepage_body_alter_focusedarticlepage_body"), + ] + + operations = [ + migrations.RemoveField( + model_name="articlepage", + name="mark_new_on_next_publish", + ), + migrations.RemoveField( + model_name="articlepage", + name="newly_published_at", + ), + migrations.RemoveField( + model_name="focusedarticlepage", + name="mark_new_on_next_publish", + ), + migrations.RemoveField( + model_name="focusedarticlepage", + name="newly_published_at", + ), + migrations.RemoveField( + model_name="recordarticlepage", + name="mark_new_on_next_publish", + ), + migrations.RemoveField( + model_name="recordarticlepage", + name="newly_published_at", + ), + migrations.AddField( + model_name="articlepage", + name="published_date", + field=models.DateTimeField( + default=django.utils.timezone.now, + help_text="The date the page was published to the public.", + verbose_name="Published date", + ), + ), + migrations.AddField( + model_name="focusedarticlepage", + name="published_date", + field=models.DateTimeField( + default=django.utils.timezone.now, + help_text="The date the page was published to the public.", + verbose_name="Published date", + ), + ), + migrations.AddField( + model_name="recordarticlepage", + name="published_date", + field=models.DateTimeField( + default=django.utils.timezone.now, + help_text="The date the page was published to the public.", + verbose_name="Published date", + ), + ), + ] diff --git a/etna/articles/models.py b/etna/articles/models.py index b12675b13..b20fb09a5 100755 --- a/etna/articles/models.py +++ b/etna/articles/models.py @@ -32,7 +32,7 @@ BasePageWithRequiredIntro, ContentWarningMixin, HeroImageMixin, - NewLabelMixin, + PublishedDateMixin, RequiredHeroImageMixin, ) from etna.core.serializers import ( @@ -171,9 +171,9 @@ def article_pages(self): .live() .order_by( Coalesce( - "recordarticlepage__newly_published_at", - "focusedarticlepage__newly_published_at", - "articlepage__newly_published_at", + "recordarticlepage__published_date", + "focusedarticlepage__published_date", + "articlepage__published_date", ) ) .reverse() @@ -205,7 +205,7 @@ class ArticlePage( TopicalPageMixin, RequiredHeroImageMixin, ContentWarningMixin, - NewLabelMixin, + PublishedDateMixin, ArticleTagMixin, BasePageWithRequiredIntro, ): @@ -236,7 +236,7 @@ class Meta: ) promote_panels = ( - NewLabelMixin.promote_panels + PublishedDateMixin.promote_panels + BasePageWithRequiredIntro.promote_panels + ArticleTagMixin.promote_panels + [ @@ -259,16 +259,17 @@ class Meta: ) default_api_fields = BasePageWithRequiredIntro.default_api_fields + [ - APIField("is_newly_published"), + PublishedDateMixin.get_is_newly_published_apifield(), ] api_fields = ( BasePageWithRequiredIntro.api_fields + RequiredHeroImageMixin.api_fields + ContentWarningMixin.api_fields - + NewLabelMixin.api_fields + ArticleTagMixin.api_fields + [ + PublishedDateMixin.get_published_date_apifield(), + PublishedDateMixin.get_is_newly_published_apifield(), APIField("body"), APIField( "similar_items", @@ -358,9 +359,9 @@ def latest_items( .prefetch_related("teaser_image__renditions") ) - return sorted( - latest_query_set, key=lambda x: x.newly_published_at, reverse=True - )[:3] + return sorted(latest_query_set, key=lambda x: x.published_date, reverse=True)[ + :3 + ] class FocusedArticlePage( @@ -368,7 +369,7 @@ class FocusedArticlePage( AuthorPageMixin, HeroImageMixin, ContentWarningMixin, - NewLabelMixin, + PublishedDateMixin, ArticleTagMixin, BasePageWithRequiredIntro, ): @@ -399,7 +400,7 @@ class Meta: ) promote_panels = ( - NewLabelMixin.promote_panels + PublishedDateMixin.promote_panels + BasePageWithRequiredIntro.promote_panels + ArticleTagMixin.promote_panels + [ @@ -424,16 +425,17 @@ class Meta: ) default_api_fields = BasePageWithRequiredIntro.default_api_fields + [ - APIField("is_newly_published"), + PublishedDateMixin.get_is_newly_published_apifield(), ] api_fields = ( BasePageWithRequiredIntro.api_fields + HeroImageMixin.api_fields + ContentWarningMixin.api_fields - + NewLabelMixin.api_fields + ArticleTagMixin.api_fields + [ + PublishedDateMixin.get_is_newly_published_apifield(), + PublishedDateMixin.get_published_date_apifield(), APIField("type_label"), APIField("body"), APIField( @@ -525,9 +527,9 @@ def latest_items( .prefetch_related("teaser_image__renditions") ) - return sorted( - latest_query_set, key=lambda x: x.newly_published_at, reverse=True - )[:3] + return sorted(latest_query_set, key=lambda x: x.published_date, reverse=True)[ + :3 + ] class PageGalleryImage(Orderable): @@ -577,7 +579,7 @@ class Meta: class RecordArticlePage( TopicalPageMixin, ContentWarningMixin, - NewLabelMixin, + PublishedDateMixin, ArticleTagMixin, BasePageWithRequiredIntro, ): @@ -709,7 +711,7 @@ class Meta: ) promote_panels = ( - NewLabelMixin.promote_panels + PublishedDateMixin.promote_panels + BasePageWithRequiredIntro.promote_panels + ArticleTagMixin.promote_panels + [ @@ -731,15 +733,16 @@ class Meta: ) default_api_fields = BasePageWithRequiredIntro.default_api_fields + [ - APIField("is_newly_published"), + PublishedDateMixin.get_is_newly_published_apifield(), ] api_fields = ( BasePageWithRequiredIntro.api_fields + ContentWarningMixin.api_fields - + NewLabelMixin.api_fields + ArticleTagMixin.api_fields + [ + PublishedDateMixin.get_is_newly_published_apifield(), + PublishedDateMixin.get_published_date_apifield(), APIField("type_label"), APIField("date_text"), APIField("about", serializer=RichTextSerializer()), diff --git a/etna/blog/migrations/0007_remove_blogindexpage_hero_image_and_more.py b/etna/blog/migrations/0007_remove_blogindexpage_hero_image_and_more.py new file mode 100644 index 000000000..8dd9db13a --- /dev/null +++ b/etna/blog/migrations/0007_remove_blogindexpage_hero_image_and_more.py @@ -0,0 +1,31 @@ +# Generated by Django 5.1.2 on 2024-12-19 16:48 + +import django.utils.timezone +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("blog", "0006_alter_blogpostpage_body"), + ] + + operations = [ + migrations.RemoveField( + model_name="blogindexpage", + name="hero_image", + ), + migrations.RemoveField( + model_name="blogindexpage", + name="hero_image_caption", + ), + migrations.AlterField( + model_name="blogpostpage", + name="published_date", + field=models.DateTimeField( + default=django.utils.timezone.now, + help_text="The date the page was published to the public.", + verbose_name="Published date", + ), + ), + ] diff --git a/etna/blog/models.py b/etna/blog/models.py index c5c909120..8919ce81e 100644 --- a/etna/blog/models.py +++ b/etna/blog/models.py @@ -1,7 +1,3 @@ -from django.db import models -from django.utils import timezone -from django.utils.functional import cached_property - from wagtail.admin.panels import FieldPanel from wagtail.api import APIField from wagtail.fields import StreamField @@ -10,8 +6,8 @@ BasePageWithRequiredIntro, ContentWarningMixin, HeroImageMixin, + PublishedDateMixin, ) -from etna.core.serializers import DateTimeSerializer, DefaultPageSerializer from etna.people.models import AuthorPageMixin, ExternalAuthorMixin from .blocks import BlogPostPageStreamBlock @@ -55,16 +51,14 @@ class BlogPage(HeroImageMixin, BasePageWithRequiredIntro): promote_panels = BasePageWithRequiredIntro.promote_panels - api_fields = ( - BasePageWithRequiredIntro.api_fields - + HeroImageMixin.api_fields - ) + api_fields = BasePageWithRequiredIntro.api_fields + HeroImageMixin.api_fields class BlogPostPage( AuthorPageMixin, ExternalAuthorMixin, ContentWarningMixin, + PublishedDateMixin, HeroImageMixin, BasePageWithRequiredIntro, ): @@ -79,12 +73,6 @@ class BlogPostPage( BlogPostPageStreamBlock(), ) - published_date = models.DateTimeField( - verbose_name="Published date", - help_text="The date the blog post was published.", - default=timezone.now, - ) - content_panels = ( BasePageWithRequiredIntro.content_panels + HeroImageMixin.content_panels @@ -93,17 +81,21 @@ class BlogPostPage( ] ) - promote_panels = BasePageWithRequiredIntro.promote_panels + [ - FieldPanel("published_date"), - AuthorPageMixin.get_authors_inlinepanel(), - ExternalAuthorMixin.get_authors_inlinepanel(), - ] + promote_panels = ( + BasePageWithRequiredIntro.promote_panels + + PublishedDateMixin.promote_panels + + [ + AuthorPageMixin.get_authors_inlinepanel(), + ExternalAuthorMixin.get_authors_inlinepanel(), + ] + ) default_api_fields = ( BasePageWithRequiredIntro.default_api_fields + AuthorPageMixin.default_api_fields + [ - APIField("published_date", serializer=DateTimeSerializer()), + PublishedDateMixin.get_published_date_apifield(), + PublishedDateMixin.get_is_newly_published_apifield(), APIField("last_published_at"), ] ) @@ -115,7 +107,8 @@ class BlogPostPage( + AuthorPageMixin.api_fields + ExternalAuthorMixin.api_fields + [ - APIField("published_date", serializer=DateTimeSerializer()), + PublishedDateMixin.get_published_date_apifield(), + PublishedDateMixin.get_is_newly_published_apifield(), APIField("body"), ] ) diff --git a/etna/collections/models.py b/etna/collections/models.py index c662f7e68..7b616ba8e 100644 --- a/etna/collections/models.py +++ b/etna/collections/models.py @@ -377,7 +377,7 @@ def related_articles(self): .prefetch_related("teaser_image__renditions") ) - return sorted(page_list, key=lambda x: x.newly_published_at, reverse=True) + return sorted(page_list, key=lambda x: x.published_date, reverse=True) @cached_property def related_highlight_gallery_pages(self): @@ -583,7 +583,7 @@ def related_articles(self): .prefetch_related("teaser_image__renditions") ) - return sorted(page_list, key=lambda x: x.newly_published_at, reverse=True) + return sorted(page_list, key=lambda x: x.published_date, reverse=True) @cached_property def related_highlight_gallery_pages(self): diff --git a/etna/core/models/mixins.py b/etna/core/models/mixins.py index ed7d1231b..916982911 100644 --- a/etna/core/models/mixins.py +++ b/etna/core/models/mixins.py @@ -12,6 +12,7 @@ from wagtail.images import get_image_model_string from etna.core.serializers import ( + DateTimeSerializer, DetailedImageSerializer, ImageSerializer, RichTextSerializer, @@ -23,10 +24,10 @@ __all__ = [ "AccentColourMixin", "ContentWarningMixin", - "NewLabelMixin", "HeroImageMixin", "HeroLayoutMixin", "HeroStyleMixin", + "PublishedDateMixin", "RequiredHeroImageMixin", "SidebarMixin", "SocialMixin", @@ -71,82 +72,42 @@ class Meta: abstract = True -class NewLabelMixin(models.Model): - """Mixin to allow editors to toggle 'new' label to be applied on-publish""" - - mark_new_on_next_publish = models.BooleanField( - verbose_name="mark this page as 'new' when published", - default=True, - help_text="This will set the 'new' label for 21 days", - ) - - newly_published_at = models.DateField( - editable=False, - verbose_name="Page marked as new on", - default=None, - null=True, - ) +class PublishedDateMixin(models.Model): + """Mixin to add a published date to a Page.""" new_label_display_for_days = 21 - def with_content_json(self, content): - """ - Overrides Page.with_content_json() to ensure page's `newly_published_at` - value is always preserved between revisions. - """ - obj = super().with_content_json(content) - obj.newly_published_at = self.newly_published_at - return obj - - def save(self, *args, **kwargs): - """ - Overrides Page.save() to set `newly_published_at` under the right - circumstances, and to ensure `mark_new_on_next_publish` is unset - once that wish has been fulfilled. - """ - # Set/reset newly_published_at where requested - if self.live and self.mark_new_on_next_publish: - self.newly_published_at = timezone.now().date() - self.mark_new_on_next_publish = False - - # Save page changes to the database - super().save(*args, **kwargs) - - if self.live and self.mark_new_on_next_publish and self.latest_revision: - # If `mark_new_on_next_publish` is still 'True' in the latest revision, - # The checkbox will remain checked when the page is next edited in Wagtail. - # Checking the box has had the desired effect now, so we 'uncheck' it - # in the revision content to avoid unexpected resetting. - self.latest_revision.content["mark_new_on_next_publish"] = False - self.latest_revision.save() + published_date = models.DateTimeField( + verbose_name="Published date", + help_text="The date the page was published to the public.", + default=timezone.now, + ) @cached_property def is_newly_published(self): expiry_date = timezone.now().date() - timedelta( days=self.new_label_display_for_days ) - if self.newly_published_at: - if self.newly_published_at > expiry_date: + if self.published_date: + if self.published_date > expiry_date: return True return False - promote_panels = [ - MultiFieldPanel( - [ - FieldPanel("mark_new_on_next_publish"), - FieldPanel("newly_published_at", read_only=True), - ], - heading="New label", - ) - ] - class Meta: abstract = True - api_fields = [ - APIField("is_newly_published"), + promote_panels = [ + FieldPanel("published_date"), ] + @classmethod + def get_published_date_apifield(cls) -> APIField: + return APIField("published_date", serializer=DateTimeSerializer()) + + @classmethod + def get_is_newly_published_apifield(cls) -> APIField: + return APIField("is_newly_published") + class HeroImageMixin(models.Model): """Mixin to add hero_image attribute to a Page."""