skillbox/server/users/schema.py

138 lines
4.3 KiB
Python

import graphene
from django.db.models import Prefetch, Value, CharField, Q
from django.db.models.functions import Concat
from graphene import relay, ObjectType
from graphene_django import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from graphql_relay import to_global_id
from basicknowledge.models import BasicKnowledge
from basicknowledge.queries import InstrumentNode
from books.models import Module
from books.schema.queries import ModuleNode
from users.models import User, SchoolClass, SchoolClassMember
class SchoolClassNode(DjangoObjectType):
pk = graphene.Int()
members = graphene.List('users.schema.ClassMemberNode')
code = graphene.String()
class Meta:
model = SchoolClass
filter_fields = ['name']
interfaces = (relay.Node,)
def resolve_pk(self, *args, **kwargs):
return self.id
def resolve_members(self, info, **kwargs):
return SchoolClassMember.objects.filter(school_class=self)
def resolve_code(self, info, **kwargs):
if not info.context.user.is_teacher():
return None
if self.code is None:
self.generate_code()
return self.code
class UserNode(DjangoObjectType):
pk = graphene.Int()
permissions = graphene.List(graphene.String)
selected_class = graphene.Field(SchoolClassNode)
is_teacher = graphene.Boolean()
old_classes = DjangoFilterConnectionField(SchoolClassNode)
class Meta:
model = User
filter_fields = ['username', 'email']
only_fields = ['username', 'email', 'first_name', 'last_name', 'school_classes', 'last_module', 'avatar_url',
'selected_class']
interfaces = (relay.Node,)
def resolve_pk(self, info, **kwargs):
return self.id
def resolve_permissions(self, info):
return self.get_all_permissions()
def resolve_selected_class(self, info):
return self.selected_class()
def resolve_is_teacher(self, info):
return self.is_teacher()
def resolve_school_classes(self, info):
if self.selected_class() is None: # then we don't have any class to return
return []
return SchoolClass.objects.filter(
Q(schoolclassmember__active=True, schoolclassmember__user=self) | Q(pk=self.selected_class().pk)).distinct()
def resolve_old_classes(self, info):
return SchoolClass.objects.filter(schoolclassmember__active=False, schoolclassmember__user=self)
class ClassMemberNode(ObjectType):
"""
We need to build this ourselves, because we want the active property on the node, because providing it on the
Connection or Edge for a UserNodeConnection is difficult.
"""
user = graphene.Field(UserNode)
active = graphene.Boolean()
first_name = graphene.String()
last_name = graphene.String()
is_teacher = graphene.Boolean()
id = graphene.ID()
def resolve_id(self, *args):
return to_global_id('UserNode', self.user.pk)
def resolve_active(self, *args):
return self.active
def resolve_first_name(self, *args):
return self.user.first_name
def resolve_last_name(self, *args):
return self.user.last_name
def resolve_user(self, info, **kwargs):
return self.user
def resolve_is_teacher(self, *args):
return self.user.is_teacher()
class UsersQuery(object):
me = graphene.Field(UserNode)
all_users = DjangoFilterConnectionField(UserNode)
my_activity = DjangoFilterConnectionField(ModuleNode)
my_instrument_activity = DjangoFilterConnectionField(InstrumentNode)
def resolve_me(self, info, **kwargs):
return info.context.user
def resolve_all_users(self, info, **kwargs):
if not info.context.user.is_superuser:
return User.objects.none()
else:
return User.objects.all()
def resolve_my_activity(self, info, **kwargs):
return Module.objects.all()
def resolve_my_instrument_activity(self, info, **kwargs):
return BasicKnowledge.objects.all()
class AllUsersQuery(object):
me = graphene.Field(UserNode)
all_users = DjangoFilterConnectionField(UserNode)
def resolve_all_users(self, info, **kwargs):
if not info.context.user.is_superuser:
return User.objects.none()
else:
return User.objects.all()