skillbox/server/books/schema/queries.py

207 lines
6.6 KiB
Python

import graphene
from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from api.utils import get_object
from ..models import Book, Topic, Module, Chapter, ContentBlock
class ContentBlockNode(DjangoObjectType):
mine = graphene.Boolean()
class Meta:
model = ContentBlock
only_fields = [
'slug', 'title', 'type', 'contents', 'hidden_for', 'visible_for', 'user_created'
]
filter_fields = [
'slug', 'title',
]
interfaces = (relay.Node,)
def resolve_mine(self, info, **kwargs):
return self.owner is not None and self.owner.pk == info.context.user.pk
class ChapterNode(DjangoObjectType):
content_blocks = DjangoFilterConnectionField(ContentBlockNode)
class Meta:
model = Chapter
only_fields = [
'slug', 'title', 'description',
]
filter_fields = [
'slug', 'title',
]
interfaces = (relay.Node,)
def resolve_content_blocks(self, info, **kwargs):
user = info.context.user
school_classes = user.school_classes.values_list('pk')
if user.has_perm('users.can_manage_school_class_content'): # teacher
publisher_content_blocks = ContentBlock.get_by_parent(self).filter(user_created=False)
user_created_content_blocks = ContentBlock.get_by_parent(self).filter(user_created=True, owner=user)
else: # student
publisher_content_blocks = ContentBlock.get_by_parent(self).filter(user_created=False).exclude(
hidden_for__in=school_classes)
self_created_content_blocks = ContentBlock.get_by_parent(self).filter(user_created=True, owner=user)
user_created_content_blocks = ContentBlock.get_by_parent(self).filter(user_created=True,
visible_for__in=school_classes).union(
self_created_content_blocks)
return publisher_content_blocks.union(user_created_content_blocks)
class ModuleNode(DjangoObjectType):
pk = graphene.Int()
chapters = DjangoFilterConnectionField(ChapterNode)
hero_image = graphene.String()
class Meta:
model = Module
only_fields = [
'slug', 'title', 'meta_title', 'teaser', 'intro', 'objective_groups', 'assignments', 'hero_image'
]
filter_fields = {
'slug': ['exact', 'icontains', 'in'],
'title': ['exact', 'icontains', 'in'],
}
interfaces = (relay.Node,)
def resolve_pk(self, info, **kwargs):
return self.id
def resolve_hero_image(self, info, **kwargs):
if self.hero_image:
return self.hero_image.file.url
def resolve_chapters(self, info, **kwargs):
return Chapter.get_by_parent(self)
def resolve_objective_groups(self, info, **kwargs):
user = info.context.user
school_classes = user.school_classes.values_list('pk')
if user.has_perm('users.can_manage_school_class_content'): # teacher
publisher_objective_groups = self.objective_groups.filter(owner=None)
user_created_objective_groups = self.objective_groups.filter(owner=user)
else: # student
publisher_objective_groups = self.objective_groups.filter(owner=None).exclude(
hidden_for__in=school_classes)
user_created_objective_groups = self.objective_groups.filter(owner__isnull=False,
visible_for__in=school_classes)
return publisher_objective_groups.union(user_created_objective_groups)
class TopicNode(DjangoObjectType):
pk = graphene.Int()
modules = DjangoFilterConnectionField(ModuleNode)
class Meta:
model = Topic
only_fields = [
'slug', 'title', 'meta_title', 'teaser', 'description',
]
filter_fields = {
'slug': ['exact', 'icontains', 'in'],
'title': ['exact', 'icontains', 'in'],
}
interfaces = (relay.Node,)
def resolve_pk(self, *args, **kwargs):
return self.id
def resolve_modules(self, *args, **kwargs):
return Module.get_by_parent(self)
class BookNode(DjangoObjectType):
pk = graphene.Int()
topics = DjangoFilterConnectionField(TopicNode)
class Meta:
model = Book
only_fields = [
'slug', 'title',
]
filter_fields = {
'slug': ['exact', 'icontains', 'in'],
'title': ['exact', 'icontains', 'in'],
}
interfaces = (relay.Node,)
def resolve_pk(self, *args, **kwargs):
return self.id
def resolve_topics(self, *args, **kwargs):
return Topic.get_by_parent(self)
class FilteredChapterNode(DjangoObjectType):
content_blocks = DjangoFilterConnectionField(ContentBlockNode)
class Meta:
model = Chapter
only_fields = [
'slug', 'title',
]
filter_fields = [
'slug', 'title',
]
interfaces = (relay.Node,)
def resolve_content_blocks(self, *args, **kwargs):
return ContentBlock.get_by_parent(self)
class BookQuery(object):
book = relay.Node.Field(BookNode)
topic = graphene.Field(TopicNode, slug=graphene.String())
module = graphene.Field(ModuleNode, slug=graphene.String())
chapter = relay.Node.Field(FilteredChapterNode)
content_block = relay.Node.Field(ContentBlockNode)
books = DjangoFilterConnectionField(BookNode)
topics = DjangoFilterConnectionField(TopicNode)
modules = DjangoFilterConnectionField(ModuleNode)
chapters = DjangoFilterConnectionField(FilteredChapterNode)
def resolve_books(self, *args, **kwargs):
return Book.objects.filter(**kwargs).live()
def resolve_topics(self, *args, **kwargs):
return Topic.objects.filter(**kwargs).live()
def resolve_modules(self, *args, **kwargs):
return Module.objects.filter(**kwargs).live()
def resolve_chapters(self, *args, **kwargs):
return Chapter.objects.filter(**kwargs).live()
def resolve_module(self, info, **kwargs):
slug = kwargs.get('slug')
id = kwargs.get('id')
if id is not None:
return get_object(Module, id)
if slug is not None:
return Module.objects.get(slug=slug)
return None
def resolve_topic(self, info, **kwargs):
slug = kwargs.get('slug')
id = kwargs.get('id')
if id is not None:
return get_object(Topic, id)
if slug is not None:
return Topic.objects.get(slug=slug)
return None