From e9f76bddc103f49ce5b9d250fc03f8064ef68971 Mon Sep 17 00:00:00 2001 From: dmoreno Date: Sat, 10 Dec 2022 17:48:29 -0600 Subject: [PATCH 1/5] adding k12 pages, subjects --- books/constants.py | 18 ++ books/models.py | 31 +++- pages/custom_blocks.py | 9 +- pages/models.py | 396 +++++++++++++++++++++++++++++++++++++++- snippets/models.py | 42 ++++- snippets/serializers.py | 18 +- snippets/urls.py | 1 + snippets/views.py | 17 +- 8 files changed, 522 insertions(+), 10 deletions(-) diff --git a/books/constants.py b/books/constants.py index f4821302f..850ff5da4 100644 --- a/books/constants.py +++ b/books/constants.py @@ -67,6 +67,24 @@ (YELLOW, 'Yellow'), ) + +MATH = 'math' +SOCIAL_STUDIES='social-studies' +SCIENCE = 'science' +CAREER_COLLEGE_READINESS = 'career-college-readiness' +OTHER = 'other' +NONE = 'none' + +K12_CATEGORIES = ( +(MATH, 'Math'), +(SOCIAL_STUDIES, 'Social Studies'), +(SCIENCE, 'Science'), +(CAREER_COLLEGE_READINESS, 'Career and College Readiness'), +(OTHER, 'Other'), +(NONE, 'None'), +) + + CC_BY_LICENSE_NAME = 'Creative Commons Attribution License' CC_BY_LICENSE_VERSION = '4.0' CC_BY_LICENSE_URL = 'https://creativecommons.org/licenses/by/4.0/' diff --git a/books/models.py b/books/models.py index b06d2800b..9822d5380 100644 --- a/books/models.py +++ b/books/models.py @@ -29,7 +29,7 @@ from openstax.functions import build_document_url, build_image_url from books.constants import BOOK_STATES, BOOK_COVER_TEXT_COLOR, COVER_COLORS, CC_NC_SA_LICENSE_NAME, CC_BY_LICENSE_NAME, \ - CC_BY_LICENSE_URL, CC_NC_SA_LICENSE_URL, CC_NC_SA_LICENSE_VERSION, CC_BY_LICENSE_VERSION + CC_BY_LICENSE_URL, CC_NC_SA_LICENSE_URL, CC_NC_SA_LICENSE_VERSION, CC_BY_LICENSE_VERSION, K12_CATEGORIES import snippets.models as snippets @@ -387,6 +387,22 @@ def get_subject_meta(self): APIField('subject_search_description') ] +class k12SubjectBooks(models.Model): + subject = models.ForeignKey(snippets.k12Subject, on_delete=models.SET_NULL, null=True, related_name='k12subjects_subject') + + def get_subject_name(self): + return self.subject.name + subject_name = property(get_subject_name) + + def get_subject_category(self): + return self.subject.subject_category + subject_category = property(get_subject_category) + + api_fields = [ + APIField('subject_name'), + APIField('subject_category'), + ] + class BookCategory(models.Model): category = models.ForeignKey(snippets.SubjectCategory, on_delete=models.SET_NULL, null=True, related_name='subjects_subjectcategory') @@ -441,10 +457,12 @@ class OrientationFacultyResources(Orderable, OrientationFacultyResource): class BookStudentResources(Orderable, StudentResources): book_student_resource = ParentalKey('books.Book', related_name='book_student_resources') - class BookSubjects(Orderable, SubjectBooks): book_subject = ParentalKey('books.Book', related_name='book_subjects') +class k12BookSubjects(Orderable, k12SubjectBooks): + k12book_subject = ParentalKey('books.Book', related_name='k12book_subjects') + class BookCategories(Orderable, BookCategory): book_category = ParentalKey('books.Book', related_name='book_categories') @@ -466,6 +484,7 @@ class Book(Page): salesforce_book_id = models.CharField(max_length=255, blank=True, null=True, help_text='No tracking and not included on adoption and interest forms if left blank)') updated = models.DateTimeField(blank=True, null=True, help_text='Late date web content was updated') + k12_subject = models.CharField(max_length=255, choices=K12_CATEGORIES, default='none') is_ap = models.BooleanField(default=False, help_text='Whether this book is an AP (Advanced Placement) book.') description = RichTextField( blank=True, help_text="Description shown on Book Detail page.") @@ -650,6 +669,7 @@ def get_community_resource_feature_link_url(self): FieldPanel('publish_date'), InlinePanel('book_subjects', label='Subjects'), InlinePanel('book_categories', label='Subject Categories'), + InlinePanel('k12book_subjects', label='K12 Subjects'), FieldPanel('is_ap'), FieldPanel('description', classname="full"), DocumentChooserPanel('cover'), @@ -744,6 +764,7 @@ def get_community_resource_feature_link_url(self): APIField('salesforce_book_id'), APIField('book_subjects'), APIField('book_categories'), + APIField('k12book_subjects'), APIField('is_ap'), APIField('description'), APIField('cover_url'), @@ -834,6 +855,12 @@ def subjects(self): subject_list.append(subject.subject_name) return subject_list + def k12subjects(self): + k12subject_list = [] + for k12subject in self.k12book_subjects.all(): + k12subject_list.append(k12subject.subject_name) + return k12subject_list + @property def subject_categories(self): category_list = [] diff --git a/pages/custom_blocks.py b/pages/custom_blocks.py index c67bbd476..bf25742fa 100644 --- a/pages/custom_blocks.py +++ b/pages/custom_blocks.py @@ -90,7 +90,6 @@ class CardImageBlock(blocks.StructBlock): class Meta: icon = 'image' - class StoryBlock(blocks.StructBlock): image = APIImageChooserBlock(required=False) story_text = blocks.TextBlock(required=False) @@ -133,3 +132,11 @@ class InfoBoxBlock(blocks.StructBlock): class Meta: icon = 'placeholder' +class TestimonialBlock(blocks.StructBlock): + author_icon = APIImageChooserBlock(required=False) + author = blocks.CharBlock(required=True) + testimonial = blocks.RichTextBlock(required=True) + + class Meta: + author_icon = 'image' + max_num = 4 \ No newline at end of file diff --git a/pages/models.py b/pages/models.py index b98e8ff1c..87dbc0153 100644 --- a/pages/models.py +++ b/pages/models.py @@ -16,7 +16,7 @@ from wagtail.snippets.edit_handlers import SnippetChooserPanel from openstax.functions import build_image_url, build_document_url -from books.models import Book, SubjectBooks +from books.models import Book, SubjectBooks, BookFacultyResources, BookStudentResources from webinars.models import Webinar from news.models import BlogStreamBlock # for use on the ImpactStories @@ -32,7 +32,8 @@ StoryBlock, \ TutorAdBlock, \ AboutOpenStaxBlock, \ - InfoBoxBlock + InfoBoxBlock, \ + TestimonialBlock from .custom_fields import \ Institutions, \ @@ -361,6 +362,7 @@ class Meta: content_panels = [ + FieldPanel('title', classname="full title"), FieldPanel('banner_headline'), FieldPanel('banner_description'), FieldPanel('banner_get_started_text'), @@ -446,9 +448,11 @@ class Meta: 'pages.TutorMarketing', 'pages.Subjects', 'pages.FormHeadings', + 'pages.K12MainPage', + 'pages.K12Subject', 'books.BookIndex', 'news.NewsIndex', - 'news.PressIndex' + 'news.PressIndex', ] max_count = 1 @@ -474,6 +478,204 @@ class Meta: verbose_name = "homepage" + +class K12MainPage(Page): + + banner_headline = models.CharField(default='', blank=True, max_length=255) + banner_description = models.TextField(default='', blank=True) + banner_right_image = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + features_cards = StreamField([ + ('features_cards', CardImageBlock()), + ]) + highlights_header = RichTextField(default='', blank=True) + highlights = StreamField( + blocks.StreamBlock([ + ('highlight', blocks.ListBlock(blocks.StructBlock([ + ('highlight_subheader', blocks.TextBlock(required=False)), + ('highlight_text', blocks.CharBlock(Required=False)), + ])))], max_num=3)) + highlights_icon = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + stats_grid = StreamField( + blocks.StreamBlock([ + ('stat', blocks.ListBlock(blocks.StructBlock([ + ('bold_stat_text', blocks.TextBlock(required=False)), + ('normal_stat_text', blocks.CharBlock(required=False)), + ])))], max_num=3)) + stats_image1 = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + stats_image2 = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + stats_image3 = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + subject_library_header = models.CharField(default='', blank=True, max_length=255) + subject_library_description = models.TextField(default='', blank=True) + + + + testimonials_header = models.CharField(default='', blank=True, max_length=255) + testimonials_description = models.TextField(default='', blank=True) + testimonials = StreamField([ + ('testimonials', TestimonialBlock()), + ]) + faq_header = models.CharField(default='', blank=True, max_length=255) + faqs = StreamField([ + ('faq', FAQBlock()), + ]) + rfi_image = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + rfi_header = models.CharField(default='', blank=True, max_length=255) + rfi_description = models.TextField(default='', blank=True) + sticky_header = models.CharField(default='', blank=True, max_length=255) + sticky_description = models.TextField(default='', blank=True) + + def get_sitemap_urls(self, request=None): + return [ + { + 'location': '{}/k12/{}'.format(Site.find_for_request(request).root_url, self.slug), + 'lastmod': (self.last_published_at or self.latest_revision_created_at), + } + ] + + + promote_image = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + + @property + def k12library(self): + subject_list = {} + for subject in snippets.k12Subject.objects.filter(locale=self.locale).order_by('name'): + subject_categories = {} + categories = [] + subject_categories['image'] = subject.subject_image + subject_categories['link'] = subject.subject_link + subject_categories['subject_category'] = subject.subject_category + subject_list[subject.name] = subject_categories + + return subject_list + + api_fields = [ + APIField('title'), + APIField('banner_headline'), + APIField('banner_description'), + APIField('banner_right_image'), + APIField('features_cards'), + APIField('highlights_header'), + APIField('highlights'), + APIField('highlights_icon'), + APIField('stats_grid'), + APIField('stats_image1'), + APIField('stats_image2'), + APIField('stats_image3'), + APIField('subject_library_header'), + APIField('subject_library_description'), + APIField('k12library'), + APIField('testimonials_header'), + APIField('testimonials_description'), + APIField('testimonials'), + APIField('faq_header'), + APIField('faqs'), + APIField('rfi_image'), + APIField('rfi_header'), + APIField('rfi_description'), + APIField('sticky_header'), + APIField('sticky_description'), + APIField('slug'), + APIField('seo_title'), + APIField('search_description'), + APIField('promote_image') + ] + + max_count = 1 + + class Meta: + verbose_name = "K12 Main Page" + + + content_panels = [ + FieldPanel('title', classname="full title"), + FieldPanel('banner_headline'), + FieldPanel('banner_description'), + ImageChooserPanel('banner_right_image'), + StreamFieldPanel('features_cards'), + FieldPanel('highlights_header'), + StreamFieldPanel('highlights'), + ImageChooserPanel('highlights_icon'), + StreamFieldPanel('stats_grid'), + ImageChooserPanel('stats_image1'), + ImageChooserPanel('stats_image2'), + ImageChooserPanel('stats_image3'), + FieldPanel('subject_library_header'), + FieldPanel('subject_library_description'), + FieldPanel('testimonials_header'), + FieldPanel('testimonials_description'), + StreamFieldPanel('testimonials'), + FieldPanel('faq_header'), + StreamFieldPanel('faqs'), + ImageChooserPanel('rfi_image'), + FieldPanel('rfi_header'), + FieldPanel('rfi_description'), + FieldPanel('sticky_header'), + FieldPanel('sticky_description') + ] + + promote_panels = [ + FieldPanel('slug'), + FieldPanel('seo_title'), + FieldPanel('search_description'), + ImageChooserPanel('promote_image') + ] + + + template = 'page.html' + parent_page_types = ['pages.HomePage'] + subpage_types = ['pages.K12Subject'] + + max_count = 1 + + + + class Meta: + verbose_name = "k12 Main Page" + + + class ContactUs(Page): tagline = models.CharField(max_length=255) mailing_header = models.CharField(max_length=255) @@ -2469,6 +2671,7 @@ def subjects(self): 'title': book.title, 'subjects': book.subjects(), 'subject_categories': book.subject_categories, + 'k12subject': book.k12subject(), 'is_ap': book.is_ap, 'cover_url': book.cover_url, 'cover_color': book.cover_color, @@ -2596,3 +2799,190 @@ class FormHeadings(Page): parent_page_types = ['pages.HomePage'] max_count = 1 + + + +class K12Subject(Page): + + subheader = models.TextField(default='HIGH SCHOOL') + # get title, short desc and image from snippets, select a snippet to get the data in + + # quick links - menu + + books_heading = models.TextField(default='') + books_short_desc = RichTextField(default='') + about_books_heading = models.TextField(default='About the Books') + about_books_text = models.CharField(default='FIND SUPPLEMENTAL RESOURCES', blank=True, max_length=255) + adoption_heading = models.TextField(default='Using an OpenStax resource in your classroom? Let us know!') + adoption_text = RichTextField(default="

Help us continue to make high-quality educational materials accessible by letting us know you've adopted! Our future grant funding is based on educator adoptions and the number of students we impact.

") + adoption_link_text = models.CharField(default='Report Your Adoption', max_length=255) + adoption_link = models.URLField(blank=True, default='/adoption') + quote_heading = models.TextField(default='What Our Teachers Say', blank=True,) + quote_text = models.CharField(default='', blank=True, max_length=255) + + resources_heading = models.TextField(default='Supplemental Resources') + blogs_heading = models.TextField(default='Blogs for High School Teachers', blank=True,) + rfi_heading = models.TextField(default="Don't see what you're looking for?") + rfi_text = models.CharField(default="We're here to answer any questions you may have. Complete the form to get in contact with a member of our team.", max_length=255) + + # get list of all books with k12 subject that matches page, then get the resources + + + promote_image = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + + + @property + def subject_intro(self): + for subject in snippets.k12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): + subject_intro = subject.intro_text + + return subject_intro + + @property + def subject_image(self): + for subject in snippets.k12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): + subject_image = subject.image + + return subject_image + + @property + def subject_category(self): + for subject in snippets.k12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): + subject_category = subject.subject_category + + return subject_category + + + + @property + def books(self): + books = Book.objects.order_by('path') + book_data = [] + for book in books: + k12subjects=[] + for subject in book.k12book_subjects.all(): + k12subjects.append(subject.subject_name) + subjects=[] + for subject in book.book_subjects.all(): + subjects.append(subject.subject_name) + + if book.subject_categories is not None \ + and self.title in k12subjects \ + and book.book_state not in ['retired', 'draft']: + if 'High School' in subjects: + high_school=True + else: + high_school=False + student_resources =[] + for resource in book.book_student_resources.all(): + resource_info = {} + resource_info['book']=book.title + resource_info['resource_heading']=resource.resource_heading + resource_info['resource_unlocked'] = resource.resource_unlocked + resource_info['link_document_url'] = resource.link_document_url + resource_info['link_external'] = resource.link_external + student_resources.append(resource_info) + book_data.append({ + 'id': book.id, + 'slug': 'books/{}'.format(book.slug), + 'title': book.title, + 'description': book.description, + # 'cover_url': book.cover_url, + 'cover_url': 'https://assets.openstax.org/oscms-dev/media/documents/biology-AP.png', + 'is_ap': book.is_ap, + 'is_hs': high_school, + 'cover_color': book.cover_color, + 'high_resolution_pdf_url': book.high_resolution_pdf_url, + 'low_resolution_pdf_url': book.low_resolution_pdf_url, + 'ibook_link': book.ibook_link, + 'ibook_link_volume_2': book.ibook_link_volume_2, + 'webview_link': book.webview_link, + 'webview_rex_link': book.webview_rex_link, + 'bookshare_link': book.bookshare_link, + 'kindle_link': book.kindle_link, + 'amazon_coming_soon': book.amazon_coming_soon, + 'amazon_link': book.amazon_link, + 'bookstore_coming_soon': book.bookstore_coming_soon, + 'comp_copy_available': book.comp_copy_available, + 'salesforce_abbreviation': book.salesforce_abbreviation, + 'salesforce_name': book.salesforce_name, + 'urls': book.book_urls(), + 'updated': book.updated, + 'created': book.created, + 'publish_date': book.publish_date, + 'last_updated_pdf': book.last_updated_pdf, + # 'has_student_resources': BookStudentResources.objects.filter(book_student_resource=book).exists(), + # 'has_instructor_resources': BookFacultyResources.objects.filter(book_faculty_resource=book).exists(), + 'student_resources': student_resources, + 'instructor_resources': [] + }) + return book_data + + + class Meta: + verbose_name = "K12 Subject" + + api_fields = [ + APIField('subheader'), + APIField('subject_intro'), + APIField('subject_image'), + APIField('subject_category'), + APIField('books_heading'), + APIField('books_short_desc'), + APIField('about_books_heading'), + APIField('about_books_text'), + APIField('books'), + APIField('adoption_heading'), + APIField('adoption_text'), + APIField('adoption_link_text'), + APIField('adoption_link'), + APIField('quote_heading'), + APIField('quote_text'), + APIField('resources_heading'), + APIField('blogs_heading'), + APIField('rfi_heading'), + APIField('rfi_text'), + APIField('seo_title'), + APIField('search_description'), + APIField('promote_image') + ] + + content_panels = Page.content_panels + [ + FieldPanel('subheader'), + FieldPanel('books_heading'), + FieldPanel('books_short_desc'), + FieldPanel('about_books_heading'), + FieldPanel('about_books_text'), + FieldPanel('adoption_heading'), + FieldPanel('adoption_text'), + FieldPanel('adoption_link_text'), + FieldPanel('adoption_link'), + FieldPanel('quote_heading'), + FieldPanel('quote_text'), + FieldPanel('resources_heading'), + FieldPanel('blogs_heading'), + FieldPanel('rfi_heading'), + FieldPanel('rfi_text'), + ] + + promote_panels = [ + FieldPanel('slug'), + FieldPanel('seo_title'), + FieldPanel('search_description'), + ImageChooserPanel('promote_image') + ] + + template = 'page.html' + + parent_page_types = ['pages.K12MainPage'] + + class Meta: + verbose_name = "k12subject" + + diff --git a/snippets/models.py b/snippets/models.py index 5a4bba929..be91fd912 100644 --- a/snippets/models.py +++ b/snippets/models.py @@ -9,7 +9,7 @@ from wagtail.core.models import TranslatableMixin, Orderable from wagtail.snippets.models import register_snippet from openstax.functions import build_image_url -from books.constants import BOOK_STATES, COVER_COLORS +from books.constants import BOOK_STATES, COVER_COLORS, K12_CATEGORIES class Subject(TranslatableMixin, models.Model): @@ -49,6 +49,46 @@ def __str__(self): register_snippet(Subject) +class k12Subject(TranslatableMixin, models.Model): + name = models.CharField(max_length=255) + intro_text = RichTextField(blank=True, null=True) + seo_title = models.CharField(max_length=255, null=True, blank=True) + search_description = models.CharField(max_length=255, null=True, blank=True) + image = models.ForeignKey( + 'wagtailimages.Image', + null=True, + blank=True, + on_delete=models.SET_NULL, + related_name='+' + ) + subject_category = models.CharField(max_length=255, choices=K12_CATEGORIES, default='none', + help_text='The category used in the K12 subjects listings') + subject_color = models.CharField(max_length=255, choices=COVER_COLORS, default='blue', + help_text='The color of the vertical stripe on Subject page.') + subject_link = models.CharField(max_length=255, null=True, blank=True) + + def get_subject_image(self): + return build_image_url(self.image) + + subject_image = property(get_subject_image) + + api_fields = ('name', 'intro_text', 'seo_title', 'search_description', 'subject_image', 'subject_category' , 'subject_color', 'subject_link') + + panels = [ + FieldPanel('name'), + FieldPanel('intro_text'), + FieldPanel('seo_title'), + FieldPanel('search_description'), + ImageChooserPanel('image'), + FieldPanel('subject_category'), + FieldPanel('subject_color'), + FieldPanel('subject_link'), + ] + + def __str__(self): + return self.name + +register_snippet(k12Subject) class FacultyResource(TranslatableMixin, index.Indexed, models.Model): heading = models.CharField(max_length=255) diff --git a/snippets/serializers.py b/snippets/serializers.py index 7a27742af..9a25d60fb 100644 --- a/snippets/serializers.py +++ b/snippets/serializers.py @@ -1,4 +1,4 @@ -from .models import Role, Subject, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection +from .models import Role, Subject, k12Subject, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection from rest_framework import serializers, generics @@ -25,6 +25,22 @@ class Meta: 'subject_color') + +class k12SubjectSerializer(serializers.ModelSerializer): + class Meta: + model = k12Subject + fields = ('id', + 'name', + 'description', + 'seo_title', + 'search_description', + 'subject_image', + 'subject_category' , + 'subject_color', + 'subject_link' + ) + + class ErrataContentSerializer(serializers.ModelSerializer): class Meta: model = ErrataContent diff --git a/snippets/urls.py b/snippets/urls.py index d3a51a164..a044a0abe 100644 --- a/snippets/urls.py +++ b/snippets/urls.py @@ -4,6 +4,7 @@ router = routers.SimpleRouter() router.register('roles', views.RoleViewSet) router.register('subjects', views.SubjectList, basename="Subjects") +router.register('k12subjects', views.k12SubjectList, basename="k12Subjects") router.register('erratacontent', views.ErrataContentViewSet, basename="ErrataContent") router.register('subjectcategory', views.SubjectCategoryViewSet, basename="SubjectCategory") router.register('givebanner', views.GiveBannerViewSet, basename="GiveBanner") diff --git a/snippets/views.py b/snippets/views.py index 4c0e2bcfa..62be4cfa4 100644 --- a/snippets/views.py +++ b/snippets/views.py @@ -1,7 +1,7 @@ from rest_framework import viewsets -from .models import Role, Subject, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection -from .serializers import RoleSerializer, SubjectSerializer, ErrataContentSerializer, SubjectCategorySerializer, \ +from .models import Role, Subject, k12Subject, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection +from .serializers import RoleSerializer, SubjectSerializer, k12SubjectSerializer, ErrataContentSerializer, SubjectCategorySerializer, \ GiveBannerSerializer, BlogContentTypeSerializer, BlogCollectionSerializer from rest_framework import generics, viewsets @@ -30,6 +30,19 @@ def get_queryset(self): queryset = queryset.filter(locale=convert_locale(locale)) return queryset +class k12SubjectList(viewsets.ReadOnlyModelViewSet): + serializer_class = k12SubjectSerializer + filter_backends = (DjangoFilterBackend,) + + def get_queryset(self): + queryset = k12Subject.objects.all() + name = self.request.query_params.get('name', None) + locale = self.request.query_params.get('locale', None) + if name is not None: + queryset = queryset.filter(name=name) + if locale is not None: + queryset = queryset.filter(locale=convert_locale(locale)) + return queryset class ErrataContentViewSet(viewsets.ModelViewSet): serializer_class = ErrataContentSerializer From 875bd6b166f4eb0c8e0b86e504f8c7e4461a0c7b Mon Sep 17 00:00:00 2001 From: dmoreno27 Date: Sun, 8 Jan 2023 16:55:33 -0600 Subject: [PATCH 2/5] fix class naming convention --- books/models.py | 4 ++-- snippets/models.py | 4 ++-- snippets/serializers.py | 6 +++--- snippets/urls.py | 2 +- snippets/views.py | 10 +++++----- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/books/models.py b/books/models.py index 2f107524c..3bfd5ea68 100644 --- a/books/models.py +++ b/books/models.py @@ -387,7 +387,7 @@ def get_subject_meta(self): APIField('subject_search_description') ] -class k12SubjectBooks(models.Model): +class K12SubjectBooks(models.Model): subject = models.ForeignKey(snippets.k12Subject, on_delete=models.SET_NULL, null=True, related_name='k12subjects_subject') def get_subject_name(self): @@ -460,7 +460,7 @@ class BookStudentResources(Orderable, StudentResources): class BookSubjects(Orderable, SubjectBooks): book_subject = ParentalKey('books.Book', related_name='book_subjects') -class k12BookSubjects(Orderable, k12SubjectBooks): +class K12BookSubjects(Orderable, K12SubjectBooks): k12book_subject = ParentalKey('books.Book', related_name='k12book_subjects') diff --git a/snippets/models.py b/snippets/models.py index be91fd912..3091ebbe1 100644 --- a/snippets/models.py +++ b/snippets/models.py @@ -49,7 +49,7 @@ def __str__(self): register_snippet(Subject) -class k12Subject(TranslatableMixin, models.Model): +class K12Subject(TranslatableMixin, models.Model): name = models.CharField(max_length=255) intro_text = RichTextField(blank=True, null=True) seo_title = models.CharField(max_length=255, null=True, blank=True) @@ -88,7 +88,7 @@ def get_subject_image(self): def __str__(self): return self.name -register_snippet(k12Subject) +register_snippet(K12Subject) class FacultyResource(TranslatableMixin, index.Indexed, models.Model): heading = models.CharField(max_length=255) diff --git a/snippets/serializers.py b/snippets/serializers.py index 9a25d60fb..ccddd2f63 100644 --- a/snippets/serializers.py +++ b/snippets/serializers.py @@ -1,4 +1,4 @@ -from .models import Role, Subject, k12Subject, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection +from .models import Role, Subject, K12Subject, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection from rest_framework import serializers, generics @@ -26,9 +26,9 @@ class Meta: -class k12SubjectSerializer(serializers.ModelSerializer): +class K12SubjectSerializer(serializers.ModelSerializer): class Meta: - model = k12Subject + model = K12Subject fields = ('id', 'name', 'description', diff --git a/snippets/urls.py b/snippets/urls.py index a044a0abe..1222ce535 100644 --- a/snippets/urls.py +++ b/snippets/urls.py @@ -4,7 +4,7 @@ router = routers.SimpleRouter() router.register('roles', views.RoleViewSet) router.register('subjects', views.SubjectList, basename="Subjects") -router.register('k12subjects', views.k12SubjectList, basename="k12Subjects") +router.register('k12subjects', views.K12SubjectList, basename="K12Subjects") router.register('erratacontent', views.ErrataContentViewSet, basename="ErrataContent") router.register('subjectcategory', views.SubjectCategoryViewSet, basename="SubjectCategory") router.register('givebanner', views.GiveBannerViewSet, basename="GiveBanner") diff --git a/snippets/views.py b/snippets/views.py index 62be4cfa4..3f94592b5 100644 --- a/snippets/views.py +++ b/snippets/views.py @@ -1,7 +1,7 @@ from rest_framework import viewsets -from .models import Role, Subject, k12Subject, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection -from .serializers import RoleSerializer, SubjectSerializer, k12SubjectSerializer, ErrataContentSerializer, SubjectCategorySerializer, \ +from .models import Role, Subject, K12Subject, ErrataContent, SubjectCategory, GiveBanner, BlogContentType, BlogCollection +from .serializers import RoleSerializer, SubjectSerializer, K12SubjectSerializer, ErrataContentSerializer, SubjectCategorySerializer, \ GiveBannerSerializer, BlogContentTypeSerializer, BlogCollectionSerializer from rest_framework import generics, viewsets @@ -30,12 +30,12 @@ def get_queryset(self): queryset = queryset.filter(locale=convert_locale(locale)) return queryset -class k12SubjectList(viewsets.ReadOnlyModelViewSet): - serializer_class = k12SubjectSerializer +class K12SubjectList(viewsets.ReadOnlyModelViewSet): + serializer_class = K12SubjectSerializer filter_backends = (DjangoFilterBackend,) def get_queryset(self): - queryset = k12Subject.objects.all() + queryset = K12Subject.objects.all() name = self.request.query_params.get('name', None) locale = self.request.query_params.get('locale', None) if name is not None: From 10eea3078c48b25b380bb45abcf2e5e70898e461 Mon Sep 17 00:00:00 2001 From: dmoreno27 Date: Tue, 10 Jan 2023 10:52:01 -0600 Subject: [PATCH 3/5] added student and instructor resources to k12 subject pages --- books/constants.py | 20 +++++++++++++++++--- books/models.py | 2 +- pages/models.py | 34 ++++++++++------------------------ 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/books/constants.py b/books/constants.py index 850ff5da4..a6ad47e87 100644 --- a/books/constants.py +++ b/books/constants.py @@ -67,19 +67,33 @@ (YELLOW, 'Yellow'), ) - MATH = 'math' SOCIAL_STUDIES='social-studies' SCIENCE = 'science' -CAREER_COLLEGE_READINESS = 'career-college-readiness' +ENGLISH = 'english' +CAREER_TECHNICAL = 'career-technical' +COLLEGE_READINESS = 'college_readiness' +FINE_ARTS = 'fine_arts' +HEALTH = 'health' +LANGUAGES = 'languages' +PHYSICAL_ED = 'physical_education' +TECHNOLOGY_APPLICATIONS = 'technology_applications' OTHER = 'other' NONE = 'none' + K12_CATEGORIES = ( (MATH, 'Math'), (SOCIAL_STUDIES, 'Social Studies'), (SCIENCE, 'Science'), -(CAREER_COLLEGE_READINESS, 'Career and College Readiness'), +(ENGLISH, 'English Language Areas & Reading'), +(CAREER_TECHNICAL, 'Career and Technical Education'), +(COLLEGE_READINESS, 'College Readiness'), +(FINE_ARTS, 'Fine Arts'), +(HEALTH, 'Health Education'), +(LANGUAGES, 'Languages other than English'), +(PHYSICAL_ED, 'Physical Education'), +(TECHNOLOGY_APPLICATIONS, 'Technology Applications'), (OTHER, 'Other'), (NONE, 'None'), ) diff --git a/books/models.py b/books/models.py index 3bfd5ea68..69f75ac6c 100644 --- a/books/models.py +++ b/books/models.py @@ -388,7 +388,7 @@ def get_subject_meta(self): ] class K12SubjectBooks(models.Model): - subject = models.ForeignKey(snippets.k12Subject, on_delete=models.SET_NULL, null=True, related_name='k12subjects_subject') + subject = models.ForeignKey(snippets.K12Subject, on_delete=models.SET_NULL, null=True, related_name='k12subjects_subject') def get_subject_name(self): return self.subject.name diff --git a/pages/models.py b/pages/models.py index 677ab351b..0f6c567a7 100644 --- a/pages/models.py +++ b/pages/models.py @@ -582,9 +582,10 @@ def get_sitemap_urls(self, request=None): @property def k12library(self): subject_list = {} - for subject in snippets.k12Subject.objects.filter(locale=self.locale).order_by('name'): + for subject in snippets.K12Subject.objects.filter(locale=self.locale).order_by('name'): subject_categories = {} categories = [] + subject_categories['color'] = subject.subject_color subject_categories['image'] = subject.subject_image subject_categories['link'] = subject.subject_link subject_categories['subject_category'] = subject.subject_category @@ -674,7 +675,7 @@ class Meta: class Meta: - verbose_name = "k12 Main Page" + verbose_name = "K12 Main Page" @@ -2827,7 +2828,6 @@ class K12Subject(Page): rfi_heading = models.TextField(default="Don't see what you're looking for?") rfi_text = models.CharField(default="We're here to answer any questions you may have. Complete the form to get in contact with a member of our team.", max_length=255) - # get list of all books with k12 subject that matches page, then get the resources promote_image = models.ForeignKey( @@ -2841,21 +2841,21 @@ class K12Subject(Page): @property def subject_intro(self): - for subject in snippets.k12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): + for subject in snippets.K12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): subject_intro = subject.intro_text return subject_intro @property def subject_image(self): - for subject in snippets.k12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): + for subject in snippets.K12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): subject_image = subject.image return subject_image @property def subject_category(self): - for subject in snippets.k12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): + for subject in snippets.K12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): subject_category = subject.subject_category return subject_category @@ -2881,15 +2881,6 @@ def books(self): high_school=True else: high_school=False - student_resources =[] - for resource in book.book_student_resources.all(): - resource_info = {} - resource_info['book']=book.title - resource_info['resource_heading']=resource.resource_heading - resource_info['resource_unlocked'] = resource.resource_unlocked - resource_info['link_document_url'] = resource.link_document_url - resource_info['link_external'] = resource.link_external - student_resources.append(resource_info) book_data.append({ 'id': book.id, 'slug': 'books/{}'.format(book.slug), @@ -2919,16 +2910,10 @@ def books(self): 'created': book.created, 'publish_date': book.publish_date, 'last_updated_pdf': book.last_updated_pdf, - # 'has_student_resources': BookStudentResources.objects.filter(book_student_resource=book).exists(), - # 'has_instructor_resources': BookFacultyResources.objects.filter(book_faculty_resource=book).exists(), - 'student_resources': student_resources, - 'instructor_resources': [] + 'student_resources': BookStudentResources.objects.values(), + 'instructor_resources': BookFacultyResources.objects.values() }) return book_data - - - class Meta: - verbose_name = "K12 Subject" api_fields = [ APIField('subheader'), @@ -2984,8 +2969,9 @@ class Meta: parent_page_types = ['pages.K12MainPage'] + class Meta: - verbose_name = "k12subject" + verbose_name = "K12 Subject" From 15ce7670ef2b7bfdf5620294aaf658f66abe5946 Mon Sep 17 00:00:00 2001 From: dmoreno27 Date: Tue, 10 Jan 2023 11:25:51 -0600 Subject: [PATCH 4/5] Tidy pages/model.py --- pages/models.py | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/pages/models.py b/pages/models.py index 0f6c567a7..514793845 100644 --- a/pages/models.py +++ b/pages/models.py @@ -584,13 +584,11 @@ def k12library(self): subject_list = {} for subject in snippets.K12Subject.objects.filter(locale=self.locale).order_by('name'): subject_categories = {} - categories = [] subject_categories['color'] = subject.subject_color subject_categories['image'] = subject.subject_image subject_categories['link'] = subject.subject_link subject_categories['subject_category'] = subject.subject_category subject_list[subject.name] = subject_categories - return subject_list api_fields = [ @@ -2808,9 +2806,6 @@ class FormHeadings(Page): class K12Subject(Page): subheader = models.TextField(default='HIGH SCHOOL') - # get title, short desc and image from snippets, select a snippet to get the data in - - # quick links - menu books_heading = models.TextField(default='') books_short_desc = RichTextField(default='') @@ -2822,13 +2817,10 @@ class K12Subject(Page): adoption_link = models.URLField(blank=True, default='/adoption') quote_heading = models.TextField(default='What Our Teachers Say', blank=True,) quote_text = models.CharField(default='', blank=True, max_length=255) - resources_heading = models.TextField(default='Supplemental Resources') blogs_heading = models.TextField(default='Blogs for High School Teachers', blank=True,) rfi_heading = models.TextField(default="Don't see what you're looking for?") rfi_text = models.CharField(default="We're here to answer any questions you may have. Complete the form to get in contact with a member of our team.", max_length=255) - - promote_image = models.ForeignKey( 'wagtailimages.Image', @@ -2838,7 +2830,6 @@ class K12Subject(Page): related_name='+' ) - @property def subject_intro(self): for subject in snippets.K12Subject.objects.filter(locale=self.locale, name=self.title).order_by('name'): @@ -2860,8 +2851,6 @@ def subject_category(self): return subject_category - - @property def books(self): books = Book.objects.order_by('path') @@ -2874,13 +2863,9 @@ def books(self): for subject in book.book_subjects.all(): subjects.append(subject.subject_name) - if book.subject_categories is not None \ + if book.k12book_subjects is not None \ and self.title in k12subjects \ and book.book_state not in ['retired', 'draft']: - if 'High School' in subjects: - high_school=True - else: - high_school=False book_data.append({ 'id': book.id, 'slug': 'books/{}'.format(book.slug), @@ -2889,7 +2874,7 @@ def books(self): # 'cover_url': book.cover_url, 'cover_url': 'https://assets.openstax.org/oscms-dev/media/documents/biology-AP.png', 'is_ap': book.is_ap, - 'is_hs': high_school, + 'is_hs': 'High School' in subjects, 'cover_color': book.cover_color, 'high_resolution_pdf_url': book.high_resolution_pdf_url, 'low_resolution_pdf_url': book.low_resolution_pdf_url, From 2a20a9887932b5d47a5e523cf3f45084ece2557c Mon Sep 17 00:00:00 2001 From: dmoreno27 Date: Thu, 12 Jan 2023 08:30:44 -0600 Subject: [PATCH 5/5] remove seo title and search description from snippets/models --- snippets/models.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/snippets/models.py b/snippets/models.py index 3091ebbe1..4acb3664b 100644 --- a/snippets/models.py +++ b/snippets/models.py @@ -52,8 +52,6 @@ def __str__(self): class K12Subject(TranslatableMixin, models.Model): name = models.CharField(max_length=255) intro_text = RichTextField(blank=True, null=True) - seo_title = models.CharField(max_length=255, null=True, blank=True) - search_description = models.CharField(max_length=255, null=True, blank=True) image = models.ForeignKey( 'wagtailimages.Image', null=True, @@ -72,13 +70,11 @@ def get_subject_image(self): subject_image = property(get_subject_image) - api_fields = ('name', 'intro_text', 'seo_title', 'search_description', 'subject_image', 'subject_category' , 'subject_color', 'subject_link') + api_fields = ('name', 'intro_text', 'subject_image', 'subject_category' , 'subject_color', 'subject_link') panels = [ FieldPanel('name'), FieldPanel('intro_text'), - FieldPanel('seo_title'), - FieldPanel('search_description'), ImageChooserPanel('image'), FieldPanel('subject_category'), FieldPanel('subject_color'),