from itertools import chain import graphene from django.db.models import Q from graphene import relay from graphene_django import DjangoObjectType from graphene_django.filter import DjangoFilterConnectionField from api.utils import get_object from books.models import Book, Topic, Module, Chapter, ContentBlock from books.schema.queries import BookNode, TopicNode, ModuleNode, ContentBlockNode class FilteredChapterNode(DjangoObjectType): content_blocks = DjangoFilterConnectionField(ContentBlockNode, user_groups=graphene.List(graphene.String)) class Meta: model = Chapter only_fields = [ 'slug', 'title', ] filter_fields = [ 'slug', 'title', ] interfaces = (relay.Node,) def resolve_content_blocks(self, *args, **kwargs): user_groups = kwargs.get('user_groups') if user_groups: reduced = [] for user_group in user_groups: content_blocks = ContentBlock.get_by_parent(self).exclude( Q(visible_to__user_group__name=user_group) ) reduced = chain(reduced, content_blocks) filtered = list(set(reduced)) return filtered else: return ContentBlock.get_by_parent(self) class VisibilityNode(DjangoObjectType): class Meta: model = Chapter filter_fields = ['user_group', 'content_block'] interfaces = (relay.Node,) class BookQuery(object): book = relay.Node.Field(BookNode) topic = relay.Node.Field(TopicNode) 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