import graphene from books.models import Chapter, ContentBlock from books.schema.interfaces import ChapterInterface from django.db.models import Q from graphene import relay from graphene_django import DjangoObjectType from notes.models import ChapterBookmark class ChapterNode(DjangoObjectType): bookmark = graphene.Field("notes.schema.ChapterBookmarkNode") content_blocks = graphene.List("books.schema.nodes.ContentBlockNode") title_hidden_for = graphene.List("users.schema.SchoolClassNode") description_hidden_for = graphene.List("users.schema.SchoolClassNode") path = graphene.String() highlights = graphene.List("notes.schema.HighlightNode") class Meta: model = Chapter only_fields = [ "slug", "title", "description", "title_hidden_for", "description_hidden_for", ] filter_fields = [ "slug", "title", ] interfaces = (relay.Node, ChapterInterface) def resolve_content_blocks(self, info, **kwargs): user = info.context.user school_classes = user.school_classes.values_list("pk", flat=True) by_parent = ContentBlock.get_by_parent(self).filter( contentblocksnapshot__isnull=True ) # exclude snapshot # .prefetch_related('visible_for') \ # .prefetch_related('hidden_for') # don't filter the hidden blocks on the server any more, we do this on the client now, as they are not secret default_blocks = Q(user_created=False) owned_by_user = Q(user_created=True, owner=user) teacher_created_and_visible = Q( Q(user_created=True) & Q(visible_for__pk__in=school_classes) ) if user.can_manage_school_class_content: # teacher return by_parent.filter( default_blocks | owned_by_user | teacher_created_and_visible ).distinct() else: # student return by_parent.filter( default_blocks | teacher_created_and_visible ).distinct() def resolve_bookmark(self, info, **kwargs): return ChapterBookmark.objects.filter( user=info.context.user, chapter=self ).first() @staticmethod def resolve_title_hidden_for(parent: Chapter, info, **kwargs): return parent.title_hidden_for.all() @staticmethod def resolve_description_hidden_for(parent: Chapter, info, **kwargs): return parent.description_hidden_for.all() @staticmethod def resolve_path(root: Chapter, info, **kwargs): module = root.get_parent() return f"module/{module.slug}#{root.graphql_id}" @staticmethod def resolve_highlights(root: Chapter, info, **kwargs): return root.highlights.filter(user=info.context.user)