diff --git a/books/migrations/0156_book_content_warning.py b/books/migrations/0156_book_content_warning.py new file mode 100644 index 000000000..1cfb5c6f0 --- /dev/null +++ b/books/migrations/0156_book_content_warning.py @@ -0,0 +1,26 @@ +# Generated by Django 5.0.6 on 2024-06-26 16:58 + +import django.db.models.deletion +from django.db import migrations, models + +class Migration(migrations.Migration): + + dependencies = [ + ("books", "0155_alter_book_book_cover_text_color_and_more"), + ("snippets", "0036_contentwarning"), + ] + + operations = [ + migrations.AddField( + model_name="book", + name="content_warning", + field=models.ForeignKey( + blank=True, + help_text="Message shown in the content warning modal.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="content_warnings_content_warning", + to="snippets.contentwarning", + ), + ), + ] diff --git a/books/models.py b/books/models.py index 065b38fe7..03e3f5086 100644 --- a/books/models.py +++ b/books/models.py @@ -551,6 +551,14 @@ class Book(Page): description = RichTextField( blank=True, help_text="Description shown on Book Detail page.") + content_warning = models.ForeignKey( + snippets.ContentWarning, + on_delete=models.SET_NULL, + null=True, + blank=True, + related_name='content_warnings_content_warning', + help_text="Message shown in the content warning modal.") + cover = models.ForeignKey( 'wagtaildocs.Document', null=True, blank=True, @@ -731,7 +739,7 @@ def get_community_resource_feature_link_url(self): support_statement = models.TextField(blank=True, null=True, default="With philanthropic support, this book is used in classrooms, saving students dollars this school year. Learn more about our impact and how you can help.", help_text="Updating this statement updates it for all book pages.") - + promote_snippet = StreamField(PromoteSnippetBlock(), null=True, blank=True, use_json_field=True) videos = StreamField([ @@ -773,6 +781,7 @@ def get_community_resource_feature_link_url(self): InlinePanel('k12book_subjects', label='K12 Subjects'), FieldPanel('is_ap'), FieldPanel('description', classname="full"), + FieldPanel('content_warning'), FieldPanel('cover'), FieldPanel('title_image'), FieldPanel('cover_color'), @@ -870,6 +879,7 @@ def get_community_resource_feature_link_url(self): APIField('k12book_subjects'), APIField('is_ap'), APIField('description'), + APIField('content_warning_text'), APIField('cover_url'), APIField('title_image_url'), APIField('cover_color'), @@ -978,6 +988,10 @@ def errata_content(self): return snippets.ErrataContent.objects.filter(locale=self.locale).first().content return snippets.ErrataContent.objects.filter(book_state=self.book_state, locale=self.locale).first().content + @property + def content_warning_text(self): + return self.content_warning.content_warning if self.content_warning else None + def get_slug(self): return 'books/{}'.format(self.slug) diff --git a/snippets/migrations/0036_contentwarning.py b/snippets/migrations/0036_contentwarning.py new file mode 100644 index 000000000..ccaf91ef9 --- /dev/null +++ b/snippets/migrations/0036_contentwarning.py @@ -0,0 +1,37 @@ +# Generated by Django 5.0.6 on 2024-06-25 18:22 + +import django.db.models.deletion +import uuid +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("snippets", "0035_alter_k12subject_subject_color_and_more"), + ("wagtailcore", "0089_log_entry_data_json_null_to_object"), + ] + + operations = [ + migrations.CreateModel( + name="ContentWarning", + fields=[ + ("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), + ("translation_key", models.UUIDField(default=uuid.uuid4, editable=False)), + ("content_warning", models.TextField()), + ( + "locale", + models.ForeignKey( + editable=False, + on_delete=django.db.models.deletion.PROTECT, + related_name="+", + to="wagtailcore.locale", + ), + ), + ], + options={ + "abstract": False, + "unique_together": {("translation_key", "locale")}, + }, + ), + ] diff --git a/snippets/models.py b/snippets/models.py index 9e43b85ce..e0a461d37 100644 --- a/snippets/models.py +++ b/snippets/models.py @@ -485,3 +485,19 @@ def __str__(self): register_snippet(AmazonBookBlurb) + +class ContentWarning(TranslatableMixin, models.Model): + content_warning = models.TextField() + + api_fields = ('content_warning') + + panels = [ + FieldPanel('content_warning') + ] + + def __str__(self): + return (self.content_warning[:100] + '...') if len(self.content_warning) > 100 else self.content_warning + + + +register_snippet(ContentWarning) diff --git a/snippets/serializers.py b/snippets/serializers.py index c60b2fee7..216d1eb2f 100644 --- a/snippets/serializers.py +++ b/snippets/serializers.py @@ -39,11 +39,11 @@ class K12SubjectSerializer(serializers.ModelSerializer): class Meta: model = K12Subject fields = ('id', - 'name', - 'intro_text', - 'subject_image', - 'subject_category' , - 'subject_color', + 'name', + 'intro_text', + 'subject_image', + 'subject_category' , + 'subject_color', 'subject_link' ) read_only_fields = ('id', @@ -132,5 +132,3 @@ class Meta: model = AmazonBookBlurb fields = ('amazon_book_blurb',) read_only_fields = ('amazon_book_blurb',) - - diff --git a/snippets/signals.py b/snippets/signals.py index 2def15780..39ef27cb2 100644 --- a/snippets/signals.py +++ b/snippets/signals.py @@ -2,7 +2,7 @@ from django.dispatch import receiver from global_settings.functions import invalidate_cloudfront_caches -from snippets.models import Subject, Role, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection, \ +from snippets.models import ContentWarning, Subject, Role, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection, \ WebinarCollection, AmazonBookBlurb, PromoteSnippet @@ -53,3 +53,6 @@ def clear_cloudfront_on_assignable_available_save(sender, **kwargs): def clear_cloudfront_on_amazon_book_blurb_save(sender, **kwargs): invalidate_cloudfront_caches('snippets/amazonbookblurb') +@receiver(post_save, sender=ContentWarning) +def clear_cloudfront_on_content_warning_save(sender, **kwargs): + invalidate_cloudfront_caches('snippets/contentwarning') diff --git a/snippets/tests.py b/snippets/tests.py index c08b51990..752e7c49a 100644 --- a/snippets/tests.py +++ b/snippets/tests.py @@ -6,7 +6,7 @@ from django.conf import settings from django.urls import reverse -from snippets.models import Subject, ErrataContent, GiveBanner, BlogContentType, NoWebinarMessage, K12Subject, \ +from snippets.models import ContentWarning, Subject, ErrataContent, GiveBanner, BlogContentType, NoWebinarMessage, K12Subject, \ FacultyResource, StudentResource, Role, SharedContent, NewsSource, SubjectCategory, BlogCollection, \ AmazonBookBlurb, PromoteSnippet @@ -72,6 +72,11 @@ def setUp(self): amazon_book_blurb="Amazon Book Blurb. Amazon Book Blurb. Amazon Book Blurb.") self.amazon_book_blurb.save() + self.content_warning = ContentWarning( + content_warning = "Content Warning" + ) + self.content_warning.save() + def test_can_create_subject(self): subject = Subject(name="Science", page_content="Science page content.", seo_title="Science SEO Title", @@ -151,4 +156,3 @@ def test_can_create_promote_snippet(self): promote_snippet.save() self.assertEqual(promote_snippet.name, "Assignable") -