skillbox/server/books/models/module.py

97 lines
3.5 KiB
Python

import logging
from datetime import datetime
from django.db import models
from wagtail.admin.edit_handlers import FieldPanel, TabbedInterface, ObjectList
from wagtail.core.fields import RichTextField
from wagtail.images.edit_handlers import ImageChooserPanel
from core.constants import DEFAULT_RICH_TEXT_FEATURES
from core.wagtail_utils import StrictHierarchyPage
from users.models import SchoolClass
class Module(StrictHierarchyPage):
class Meta:
verbose_name = 'Modul'
verbose_name_plural = 'Module'
meta_title = models.CharField(
max_length=255,
help_text='e.g. \'Intro\' or \'Modul 1\''
)
hero_image = models.ForeignKey(
'wagtailimages.Image',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
teaser = models.TextField()
intro = RichTextField(features=DEFAULT_RICH_TEXT_FEATURES)
solutions_enabled_for = models.ManyToManyField(SchoolClass)
content_panels = [
FieldPanel('title', classname="full title"),
FieldPanel('meta_title', classname="full title"),
ImageChooserPanel('hero_image'),
FieldPanel('teaser'),
FieldPanel('intro'),
]
settings_panels = [
FieldPanel('slug')
]
edit_handler = TabbedInterface([
ObjectList(content_panels, heading='Content'),
ObjectList(settings_panels, heading='Settings'),
])
template = 'generic_page.html'
parent_page_types = ['books.Topic']
subpage_types = ['books.Chapter']
def get_child_ids(self):
return self.get_children().values_list('id', flat=True)
def sync_from_school_class(self, school_class_template, school_class_to_sync):
# import here so we don't get a circular import error
from books.models import Chapter, ContentBlock
# get chapters of module
chapters = Chapter.get_by_parent(self)
content_block_query = ContentBlock.objects.none()
# get content blocks of chapters
for chapter in chapters:
content_block_query = content_block_query.union(ContentBlock.get_by_parent(chapter))
# clear all `hidden for` and `visible for` for class `school_class_to_sync`
for content_block in school_class_to_sync.hidden_content_blocks.intersection(content_block_query):
content_block.hidden_for.remove(school_class_to_sync)
for content_block in school_class_to_sync.visible_content_blocks.intersection(content_block_query):
content_block.visible_for.remove(school_class_to_sync)
# get all content blocks with `hidden for` for class `school_class_pattern`
for content_block in school_class_template.hidden_content_blocks.intersection(content_block_query):
# add `school_class_to_sync` to these blocks' `hidden for`
content_block.hidden_for.add(school_class_to_sync)
# get all content blocks with `visible for` for class `school_class_pattern`
for content_block in school_class_template.visible_content_blocks.intersection(content_block_query):
# add `school_class_to_sync` to these blocks' `visible for`
content_block.visible_for.add(school_class_to_sync)
class RecentModule(models.Model):
module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name='recent_modules')
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
visited = models.DateTimeField(default=datetime.now)
class Meta:
get_latest_by = 'visited'