skillbox/server/books/schema/nodes/chapter.py

103 lines
3.4 KiB
Python

import graphene
from django.db.models import Q
from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from graphql_relay import to_global_id
from books.models import Chapter, ContentBlock
from books.models.snapshot import ChapterSnapshot
from books.schema.interfaces import ChapterInterface
from notes.models import ChapterBookmark
from notes.schema import ChapterBookmarkNode
class ChapterNode(DjangoObjectType):
bookmark = graphene.Field(ChapterBookmarkNode)
content_blocks = graphene.List('books.schema.nodes.ContentBlockNode')
class Meta:
model = Chapter
only_fields = [
'slug', 'title', 'description', 'title_hidden_for', 'description_hidden_for'
]
filter_fields = [
'slug', 'title',
]
interfaces = (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()
class ChapterInSnapshotNode(DjangoObjectType):
title_hidden = graphene.Boolean()
description_hidden = graphene.Boolean()
title = graphene.String()
description = graphene.String()
id = graphene.ID(required=True)
class Meta:
model = ChapterSnapshot
only_fields = '__all__'
filter_fields = [
'id',
]
interfaces = (ChapterInterface,)
@staticmethod
def resolve_title_hidden(parent, info):
return parent.title_hidden
@staticmethod
def resolve_description_hidden(parent, info):
return parent.description_hidden
@staticmethod
def resolve_title(parent, info):
return parent.chapter.title
@staticmethod
def resolve_description(parent, info):
return parent.chapter.description
@staticmethod
def resolve_content_blocks(parent, info, **kwargs):
snapshot = parent.snapshot
user_created = Q(user_created=True)
hidden_for_snapshot = Q(hidden_for_snapshots=snapshot)
custom_hidden = Q(contentblocksnapshot__hidden=True)
qs = ContentBlock.get_by_parent(parent.chapter) \
.exclude(user_created) \
.exclude(hidden_for_snapshot) \
.exclude(custom_hidden)
return qs
def resolve_id(self, *args):
return to_global_id('SnapshotChapterNode', self.chapter.pk)