from django.contrib.auth import get_user_model from django.db import models from django.db.models import Q from books.models import Chapter, ContentBlock, ContentBlockSnapshot from objectives.models import ObjectiveSnapshot class ChapterSnapshot(models.Model): """ Captures the state of a chapter at the time when the snapshot was taken, for the school class that was selected for the user creating the snapshot """ chapter = models.ForeignKey( 'books.Chapter', related_name='chapter_snapshots', on_delete=models.PROTECT ) snapshot = models.ForeignKey( 'books.Snapshot', related_name='chapter_snapshots', on_delete=models.CASCADE ) title_hidden = models.BooleanField(default=False) description_hidden = models.BooleanField(default=False) class ObjectiveGroupSnapshot(models.Model): objective_group = models.ForeignKey( 'objectives.ObjectiveGroup', on_delete=models.CASCADE ) snapshot = models.ForeignKey( 'books.Snapshot', related_name='objective_group_snapshots', on_delete=models.CASCADE ) hidden = models.BooleanField(default=False) class SnapshotManager(models.Manager): def create_snapshot(self, module, school_class, user, *args, **kwargs): snapshot = self.create(module=module, creator=user, *args, **kwargs) chapters = Chapter.get_by_parent(module) for chapter in chapters: ChapterSnapshot.objects.create( chapter=chapter, snapshot=snapshot, title_hidden=chapter.title_hidden_for.filter(id=school_class.id).exists(), description_hidden=chapter.description_hidden_for.filter(id=school_class.id).exists() ) base_qs = ContentBlock.get_by_parent(chapter).filter(contentblocksnapshot__isnull=True) for content_block in base_qs.filter(user_created=False): if content_block.hidden_for.filter(id=school_class.id).exists(): snapshot.hidden_content_blocks.add(content_block) for content_block in base_qs.filter(Q(user_created=True) & Q(owner=user)): new_content_block = ContentBlockSnapshot( hidden=content_block.is_hidden_for_class(school_class), snapshot=snapshot, contents=content_block.contents, type=content_block.type, title=content_block.title, original_creator=content_block.owner ) content_block.add_sibling(instance=new_content_block, pos='right') revision = new_content_block.save_revision() revision.publish() new_content_block.save() for objective_group in module.objective_groups.all(): ObjectiveGroupSnapshot.objects.create( objective_group=objective_group, snapshot=snapshot, hidden=objective_group.hidden_for.filter(id=school_class.id).exists(), ) base_qs = objective_group.objectives.filter(objectivesnapshot__isnull=True) for objective in base_qs.filter(owner__isnull=True): if objective.hidden_for.filter(id=school_class.id).exists(): snapshot.hidden_objectives.add(objective) for objective in base_qs.filter(owner=user): ObjectiveSnapshot.objects.create( hidden=objective.is_hidden_for_class(school_class=school_class), snapshot=snapshot, text=objective.text, group=objective_group, order=objective.order ) return snapshot class Snapshot(models.Model): module = models.ForeignKey( 'books.Module', on_delete=models.PROTECT, related_name='snapshots' ) chapters = models.ManyToManyField( 'books.Chapter', through=ChapterSnapshot ) hidden_content_blocks = models.ManyToManyField( 'books.ContentBlock', related_name='hidden_for_snapshots' ) created = models.DateTimeField(auto_now_add=True) creator = models.ForeignKey(get_user_model(), on_delete=models.SET_NULL, null=True) shared = models.BooleanField(default=False) objective_groups = models.ManyToManyField( 'objectives.ObjectiveGroup', through=ObjectiveGroupSnapshot, related_name='+' ) hidden_objectives = models.ManyToManyField( 'objectives.Objective', related_name='hidden_for_snapshots' ) objects = SnapshotManager() def __str__(self): return f'Snapshot {self.id}'