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

68 lines
1.9 KiB
Python

import graphene
from wagtail.models import Page
from books.models import Module, Topic
from books.schema.nodes import ModuleNode
from graphene import relay
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from notes.models import Highlight
class NotFoundFailure:
reason = "Not Found"
class NotFound(graphene.ObjectType):
reason = graphene.String()
class TopicNode(DjangoObjectType):
pk = graphene.Int()
modules = graphene.List(graphene.NonNull("books.schema.nodes.ModuleNode"))
highlights = graphene.List("notes.schema.HighlightNode")
class Meta:
model = Topic
only_fields = [
"slug",
"title",
"teaser",
"description",
"vimeo_id",
"order",
"instructions",
]
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):
translations = self.get_translations()
ids = list(self.get_child_ids())
for translation in translations:
ids += list(translation.get_child_ids())
return Module.objects.filter(id__in=ids).live()
@staticmethod
def resolve_highlights(root: Topic, info, **kwargs):
# todo: is this too expensive, query-wise?
pages = Page.objects.live().descendant_of(root)
return Highlight.objects.filter(user=info.context.user).filter(page__in=pages)
class TopicOr404Node(graphene.Union):
class Meta:
types = (TopicNode, NotFound)
@classmethod
def resolve_type(cls, instance, info):
if type(instance).__name__ == "Topic":
return TopicNode
return NotFound