import graphene from django.db.models import F, Q from graphene import relay from graphene_django import DjangoObjectType from graphene_django.filter import DjangoFilterConnectionField from core.mixins import HiddenAndVisibleForMixin, HiddenForMixin from objectives.models import ObjectiveGroup, Objective class ObjectiveNode(DjangoObjectType, HiddenAndVisibleForMixin): pk = graphene.Int() user_created = graphene.Boolean() mine = graphene.Boolean() class Meta: model = Objective filter_fields = ['text'] interfaces = (relay.Node,) def resolve_objective_progress(self, info, **kwargs): return self.objective_progress.filter(user=info.context.user) def resolve_user_created(self, info, **kwargs): return self.owner is not None def resolve_mine(self, info, **kwargs): return self.owner is not None and self.owner.pk == info.context.user.pk class ObjectiveGroupNode(DjangoObjectType, HiddenForMixin): pk = graphene.Int() display_title = graphene.String() objectives = graphene.List(ObjectiveNode) class Meta: model = ObjectiveGroup filter_fields = ['title', 'module__slug'] interfaces = (relay.Node,) def resolve_pk(self, *args, **kwargs): return self.id def resolve_display_title(self, *args, **kwargs): return self.get_title_display() def resolve_objectives(self, info, **kwargs): user = info.context.user school_classes = user.school_classes.values_list('pk') base_qs = self.objectives.filter(objectivesnapshot__isnull=True) objectives_from_publisher = Q(owner=None) objectives_from_user = Q(owner=user) objectives_from_teacher = Q(owner__isnull=False, visible_for__in=school_classes) # todo # raise NotImplemented('not in correct order') # order_by = owner_last = F('owner').asc(nulls_first=True) order_first = F('order').asc(nulls_last=True) if user.has_perm('users.can_manage_school_class_content'): # teacher qs = base_qs.filter(objectives_from_publisher | objectives_from_user) else: # student qs = base_qs.filter(objectives_from_publisher | objectives_from_teacher) return qs.order_by(owner_last, order_first) class ObjectivesQuery(object): objective_group = relay.Node.Field(ObjectiveGroupNode) objective_groups = DjangoFilterConnectionField(ObjectiveGroupNode)