Esempio n. 1
0
class Attribute(CountableDjangoObjectType):
    input_type = AttributeInputTypeEnum(description=AttributeDescriptions.INPUT_TYPE)

    name = graphene.String(description=AttributeDescriptions.NAME)
    slug = graphene.String(description=AttributeDescriptions.SLUG)
    type = AttributeTypeEnum(description=AttributeDescriptions.TYPE)

    values = graphene.List(AttributeValue, description=AttributeDescriptions.VALUES)

    value_required = graphene.Boolean(
        description=AttributeDescriptions.VALUE_REQUIRED, required=True
    )
    visible_in_storefront = graphene.Boolean(
        description=AttributeDescriptions.VISIBLE_IN_STOREFRONT, required=True
    )
    filterable_in_storefront = graphene.Boolean(
        description=AttributeDescriptions.FILTERABLE_IN_STOREFRONT, required=True
    )
    filterable_in_dashboard = graphene.Boolean(
        description=AttributeDescriptions.FILTERABLE_IN_DASHBOARD, required=True
    )
    available_in_grid = graphene.Boolean(
        description=AttributeDescriptions.AVAILABLE_IN_GRID, required=True
    )

    translation = TranslationField(AttributeTranslation, type_name="attribute")

    storefront_search_position = graphene.Int(
        description=AttributeDescriptions.STOREFRONT_SEARCH_POSITION, required=True
    )

    class Meta:
        description = (
            "Custom attribute of a product. Attributes can be assigned to products and "
            "variants at the product type level."
        )
        only_fields = ["id", "product_types", "product_variant_types"]
        interfaces = [graphene.relay.Node, ObjectWithMetadata]
        model = models.Attribute

    @staticmethod
    def resolve_values(root: models.Attribute, info):
        return AttributeValuesByAttributeIdLoader(info.context).load(root.id)

    @staticmethod
    @check_attribute_required_permissions()
    def resolve_value_required(root: models.Attribute, *_args):
        return root.value_required

    @staticmethod
    @check_attribute_required_permissions()
    def resolve_visible_in_storefront(root: models.Attribute, *_args):
        return root.visible_in_storefront

    @staticmethod
    @check_attribute_required_permissions()
    def resolve_filterable_in_storefront(root: models.Attribute, *_args):
        return root.filterable_in_storefront

    @staticmethod
    @check_attribute_required_permissions()
    def resolve_filterable_in_dashboard(root: models.Attribute, *_args):
        return root.filterable_in_dashboard

    @staticmethod
    @check_attribute_required_permissions()
    def resolve_storefront_search_position(root: models.Attribute, *_args):
        return root.storefront_search_position

    @staticmethod
    @check_attribute_required_permissions()
    def resolve_available_in_grid(root: models.Attribute, *_args):
        return root.available_in_grid
Esempio n. 2
0
class ApplicationType(DjangoObjectType):
    status=graphene.Int() # to return what should user do
    message=graphene.String()  # give message to end user
    link=graphene.String() # update link
    class Meta:
        model=ApplicationVersion
Esempio n. 3
0
class BaseBulkMutation(BaseMutation):
    count = graphene.Int(required=True,
                         description="Returns how many objects were affected.")

    class Meta:
        abstract = True

    @classmethod
    def __init_subclass_with_meta__(cls, model=None, _meta=None, **kwargs):
        if not model:
            raise ImproperlyConfigured("model is required for bulk mutation")
        if not _meta:
            _meta = ModelMutationOptions(cls)
        _meta.model = model

        super().__init_subclass_with_meta__(_meta=_meta, **kwargs)

    @classmethod
    def clean_instance(cls, info, instance):
        """Perform additional logic.

        Override this method to raise custom validation error and prevent
        bulk action on the instance.
        """

    @classmethod
    def bulk_action(cls, queryset, **kwargs):
        """Implement action performed on queryset."""
        raise NotImplementedError

    @classmethod
    def perform_mutation(cls, _root, info, ids, **data):
        """Perform a mutation that deletes a list of model instances."""
        clean_instance_ids, errors = [], {}
        # Allow to pass empty list for dummy mutation
        if not ids:
            return 0, errors
        instance_model = cls._meta.model
        model_type = registry.get_type_for_model(instance_model)
        instances = cls.get_nodes_or_error(ids, "id", model_type)
        for instance, node_id in zip(instances, ids):
            instance_errors = []

            # catch individual validation errors to raise them later as
            # a single error
            try:
                cls.clean_instance(info, instance)
            except ValidationError as e:
                msg = ". ".join(e.messages)
                instance_errors.append(msg)

            if not instance_errors:
                clean_instance_ids.append(instance.pk)
            else:
                instance_errors_msg = ". ".join(instance_errors)
                ValidationError({
                    node_id: instance_errors_msg
                }).update_error_dict(errors)

        if errors:
            errors = ValidationError(errors)
        count = len(clean_instance_ids)
        if count:
            qs = instance_model.objects.filter(pk__in=clean_instance_ids)
            cls.bulk_action(queryset=qs, **data)
        return count, errors

    @classmethod
    def mutate(cls, root, info, **data):
        if not cls.check_permissions(info.context):
            raise PermissionDenied()

        count, errors = cls.perform_mutation(root, info, **data)
        if errors:
            return cls.handle_errors(errors, count=count)

        return cls(errors=errors, count=count)
Esempio n. 4
0
 class Arguments:
     id = graphene.Int(required=True)
     input = RecipeInput(required=True)
Esempio n. 5
0
 class Arguments:
     id = graphene.Int(required=True)
     book_data = BookInput(required=True)
Esempio n. 6
0
class Query(ObjectType):
    """
    Class for Queries creation :
    query1 -  all categories
    query2 -  all ingredients
    query3 -  ingredient category by name
    query4 -  ingredient by category
    query5 -  ingredient by name
    query6 -  by recipe
    query7 -  all recipes
    
    query8 - Make filter :
        - to comment (L63,L64) if you want to test file queries_test
        - to uncomment  (L63,L64) if you want to test file queries_filter_test
    """

    #Query 1
    all_categories = graphene.List(IngredientCategoryType,
                                   description="Get All categories")

    #Query 2
    all_ingredients = graphene.List(IngredientType,
                                    description="Get the list of Ingredients")

    #Query 3
    ingredientCategory = graphene.Field(
        IngredientCategoryType,
        id=graphene.Int(),
        name=graphene.String(),
        description="Get Ingredient Category by name")

    #Query 4
    category = graphene.Field(IngredientCategoryType,
                              id=graphene.Int(),
                              name=graphene.String(),
                              description="Get Category by name")

    #Query 5
    ingredient = graphene.Field(IngredientType,
                                id=graphene.Int(),
                                name=graphene.String(),
                                description="Get Ingredient by name")

    #Query 6
    recipe = graphene.Field(RecipeType,
                            id=graphene.Int(),
                            description="Get Recipe by title")

    #Query 7
    all_recipes = graphene.List(RecipeType, description="Get All Recipes")

    #Query 8 : filter to comment if you want the basic schema without filter :)
    ingredientFilter = relay.Node.Field(IngredientNode)
    all_ingredientFilter = DjangoFilterConnectionField(
        IngredientNode, description="Get All Filtered")

    def resolve_all_categories(self, info, **kwargs):
        return IngredientCategory.objects.all()

    def resolve_all_ingredients(self, info, **kwargs):
        # We can easily optimize query count in the resolve method
        return Ingredient.objects.select_related('category').all()

    def resolve_all_recipes(self, info, **kwargs):
        return Recipe.objects.all()

    def resolve_ingredientCategory(self, info, **kwargs):
        id = kwargs.get('id')
        name = kwargs.get('name')

        if id is not None:
            return IngredientCategory.objects.get(pk=id)

        if name is not None:
            return IngredientCategory.objects.get(name=name)

        return None

    def resolve_category(self, info, **kwargs):
        id = kwargs.get('id')
        name = kwargs.get('name')

        if id is not None:
            return IngredientCategory.objects.get(pk=id)

        if name is not None:
            return IngredientCategory.objects.get(name=name)

        return None

    def resolve_ingredient(self, info, **kwargs):
        id = kwargs.get('id')
        name = kwargs.get('name')

        if id is not None:
            return Ingredient.objects.get(pk=id)

        if name is not None:
            return Ingredient.objects.get(name=name)

        return None

    def resolve_recipe(self, info, **kwargs):
        id = kwargs.get('id')
        title = kwargs.get('title')

        if id is not None:
            return Recipe.objects.get(pk=id)

        if title is not None:
            return Recipe.objects.get(title=title)

        return None
Esempio n. 7
0
 class Arguments:
     name = graphene.String()
     notes = graphene.String()
     category_id = graphene.Int()
Esempio n. 8
0
    class Arguments:

        post_id = graphene.Int()
Esempio n. 9
0
class Attribute(CountableDjangoObjectType, MetadataObjectType):
    input_type = AttributeInputTypeEnum(
        description=AttributeDescriptions.INPUT_TYPE)

    name = graphene.String(description=AttributeDescriptions.NAME)
    slug = graphene.String(description=AttributeDescriptions.SLUG)

    values = gql_optimizer.field(
        graphene.List(AttributeValue,
                      description=AttributeDescriptions.VALUES),
        model_field="values",
    )

    value_required = graphene.Boolean(
        description=AttributeDescriptions.VALUE_REQUIRED, required=True)
    visible_in_storefront = graphene.Boolean(
        description=AttributeDescriptions.VISIBLE_IN_STOREFRONT, required=True)
    filterable_in_storefront = graphene.Boolean(
        description=AttributeDescriptions.FILTERABLE_IN_STOREFRONT,
        required=True)
    filterable_in_dashboard = graphene.Boolean(
        description=AttributeDescriptions.FILTERABLE_IN_DASHBOARD,
        required=True)
    available_in_grid = graphene.Boolean(
        description=AttributeDescriptions.AVAILABLE_IN_GRID, required=True)

    translation = TranslationField(AttributeTranslation, type_name="attribute")

    storefront_search_position = graphene.Int(
        description=AttributeDescriptions.STOREFRONT_SEARCH_POSITION,
        required=True)

    class Meta:
        description = (
            "Custom attribute of a product. Attributes can be assigned to products and "
            "variants at the product type level.")
        only_fields = ["id", "product_types", "product_variant_types"]
        interfaces = [relay.Node]
        model = models.Attribute

    @staticmethod
    def resolve_values(root: models.Attribute, *_args):
        return root.values.all()

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_private_meta(root, _info):
        return resolve_private_meta(root, _info)

    @staticmethod
    def resolve_meta(root, _info):
        return resolve_meta(root, _info)

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_value_required(root: models.Attribute, *_args):
        return root.value_required

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_visible_in_storefront(root: models.Attribute, *_args):
        return root.visible_in_storefront

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_filterable_in_storefront(root: models.Attribute, *_args):
        return root.filterable_in_storefront

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_filterable_in_dashboard(root: models.Attribute, *_args):
        return root.filterable_in_dashboard

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_storefront_search_position(root: models.Attribute, *_args):
        return root.storefront_search_position

    @staticmethod
    @permission_required(ProductPermissions.MANAGE_PRODUCTS)
    def resolve_available_in_grid(root: models.Attribute, *_args):
        return root.available_in_grid
Esempio n. 10
0
    class Argument:

        comment_id = graphene.Int()
        text = graphene.String()
        photo = graphene.String()
Esempio n. 11
0
    class Argument:

        comment_id = graphene.Int()
Esempio n. 12
0
    class Arguments:

        target_id = graphene.Int()
        text = graphene.String()
        photo = graphene.String()
        created_at = graphene.DateTime()
Esempio n. 13
0
 class Arguments:
     id = graphene.Int(required=True)
     input = HighlightInput(required=True)
Esempio n. 14
0
 class Arguments:
     user_id = graphene.Int(
         required=True)  # needed to know which user to update
     username = graphene.String()  # add required=False?
     password = graphene.String()  # add required=False?
     email = graphene.String()  # add required=False?
Esempio n. 15
0
 class Arguments:
     deckcard_id = graphene.Int(required=True)
Esempio n. 16
0
class TargetSSHCredential(TargetCredential):
    port = graphene.Int(description="SSH Port to connect with the credential")

    def resolve_port(root, _info):
        return get_int_from_element(root, 'port')
Esempio n. 17
0
 class Arguments:
     starter_deck_id = graphene.Int(required=True)
     user_id = graphene.Int(required=False, default_value=None)
Esempio n. 18
0
class Target(EntityObjectType):
    """Target ObjectType"""

    hosts = graphene.List(
        graphene.String,
        description="List of IPs, host names or address ranges to scan as a "
        "target",
    )
    exclude_hosts = graphene.List(
        graphene.String,
        description="List of IPs, host names or address ranges to exclude while"
        " scanning",
    )
    host_count = graphene.Int(
        description="Number of hosts to target for a scan")

    port_list = graphene.Field(PortList,
                               description="Port list to use for the target")

    ssh_credential = graphene.Field(TargetSSHCredential)
    smb_credential = graphene.Field(TargetCredential)
    esxi_credential = graphene.Field(TargetCredential)
    snmp_credential = graphene.Field(TargetCredential)

    alive_tests = graphene.String(description="Which alive test to use")
    allow_simultaneous_ips = graphene.Boolean(
        name="allowSimultaneousIPs",
        description=(
            "Whether to scan multiple IPs of the same host simultaneously"),
    )
    reverse_lookup_only = graphene.Boolean(
        description="Whether to scan only hosts that have names")
    reverse_lookup_unify = graphene.Boolean(
        description=("Whether to scan only one IP when "
                     "multiple IPs have the same name"))
    tasks = graphene.List(
        TargetTask,
        description="List of tasks that use the target",
    )

    def resolve_hosts(root, _info):
        hosts = get_text_from_element(root, 'hosts')
        return csv_to_list(hosts)

    def resolve_exclude_hosts(root, _info):
        exclude_hosts = get_text_from_element(root, 'exclude_hosts')
        return csv_to_list(exclude_hosts)

    def resolve_host_count(root, _info):
        return get_int_from_element(root, 'max_hosts')

    def resolve_port_list(root, _info):
        return root.find("port_list")

    def resolve_ssh_credential(root, _info):
        return root.find('ssh_credential')

    def resolve_smb_credential(root, _info):
        return root.find('smb_credential')

    def resolve_esxi_credential(root, _info):
        return root.find('esxi_credential')

    def resolve_snmp_credential(root, _info):
        return root.find('snmp_credential')

    def resolve_alive_tests(root, _info):
        return get_text_from_element(root, 'alive_tests')

    def resolve_allow_simultaneous_ips(root, _info):
        return get_boolean_from_element(root, "allow_simultaneous_ips")

    def resolve_reverse_lookup_only(root, _info):
        return get_boolean_from_element(root, "reverse_lookup_only")

    def resolve_reverse_lookup_unify(root, _info):
        return get_boolean_from_element(root, "reverse_lookup_unify")

    def resolve_tasks(root, _info):
        tasks = root.find('tasks')
        if len(tasks) == 0:
            return None
        return tasks.findall('task')
Esempio n. 19
0
 class Arguments:
     id = graphene.Int(required=True)
     input = IngredientCategoryInput(required=True)
Esempio n. 20
0
 class Arguments:
     link_id = graphene.Int()
Esempio n. 21
0
 class Arguments:
     id = graphene.Int(required=True)
     name = graphene.Argument(graphene.String)
     notes = graphene.String()
     category_id = graphene.Int()
Esempio n. 22
0
class Query(graphene.ObjectType):
    buildings = graphene.List(BuildingType,
                              user__id=graphene.Int(required=False),
                              token=graphene.String(required=True))
    building = graphene.Field(BuildingType,
                              id=graphene.Int(),
                              token=graphene.String(required=True))

    devices = graphene.List(DeviceUnionType,
                            building__id=graphene.Int(required=False),
                            token=graphene.String(required=True))
    device = graphene.Field(DeviceUnionType,
                            id=graphene.Int(),
                            token=graphene.String(required=True))

    measure_parameters = graphene.List(
        graphene.String,
        building__id=graphene.Int(required=False),
        token=graphene.String(required=True))

    measurements = ElasticsearchConnectionField(MeasurementType)

    measuring_devices = graphene.List(
        MeasuringDeviceType,
        building__id=graphene.Int(required=False),
        token=graphene.String(required=True))
    measuring_device = graphene.Field(MeasuringDeviceType,
                                      id=graphene.Int(),
                                      token=graphene.String(required=True))

    actuating_devices = graphene.List(
        ActuatingDeviceType,
        building__id=graphene.Int(required=False),
        token=graphene.String(required=True))
    actuating_device = graphene.Field(ActuatingDeviceType,
                                      id=graphene.Int(),
                                      token=graphene.String(required=True))

    schedules = graphene.List(ScheduleType,
                              building__id=graphene.Int(required=False),
                              ordering=graphene.Boolean(required=False),
                              token=graphene.String(required=True))
    schedule = graphene.Field(ScheduleType,
                              id=graphene.Int(),
                              ordering=graphene.Boolean(required=False),
                              token=graphene.String(required=True))

    control_parameters = graphene.List(
        ControlParameterType,
        building__id=graphene.Int(required=False),
        token=graphene.String(required=True))
    control_parameter = graphene.Field(ControlParameterType,
                                       id=graphene.Int(),
                                       token=graphene.String(required=True))

    users = graphene.List(UserType, token=graphene.String(required=True))
    user = graphene.Field(UserType,
                          id=graphene.Int(),
                          token=graphene.String(required=True))

    @login_required
    def resolve_measure_parameters(root, info, **kwargs):
        building = kwargs.get("building__id")
        if building:
            distincts = Measurement.objects.filter(
                device__building__user=info.context.user,
                device__building__id=building).order_by().values_list(
                    'measure_parameter').distinct()
        else:
            distincts = Measurement.objects.filter(
                device__building__user=info.context.user).order_by(
                ).values_list('measure_parameter').distinct()
        distincts = (list(sum(distincts, ())))
        return distincts

    @login_required
    def resolve_buildings(root, info, **kwargs):
        return Building.objects.filter(user=info.context.user)

    @login_required
    def resolve_building(root, info, id, **kwargs):
        return get_object_or_404(Building, id=id)

    @login_required
    def resolve_devices(root, info, **kwargs):
        building = kwargs.get("building__id")
        if building:
            return Device.objects.filter(building__user=info.context.user,
                                         building__id=building)
        return Device.objects.filter(building__user=info.context.user)

    @login_required
    def resolve_device(root, info, id, **kwargs):
        return get_object_or_404(Device,
                                 id=id,
                                 building__user=info.context.user)

    @login_required
    def resolve_measuring_devices(root, info, **kwargs):
        building = kwargs.get("building__id")
        if building:
            return MeasuringDevice.objects.filter(
                building__user=info.context.user, building__id=building)
        return MeasuringDevice.objects.filter(building__user=info.context.user)

    @login_required
    def resolve_measuring_device(root, info, id, **kwargs):
        return get_object_or_404(MeasuringDevice,
                                 id=id,
                                 building__user=info.context.user)

    @login_required
    def resolve_actuating_devices(root, info, **kwargs):
        building = kwargs.get("building__id")
        if building:
            return ActuatingDevice.objects.filter(
                building__user=info.context.user, building__id=building)
        return ActuatingDevice.objects.filter(building__user=info.context.user)

    @login_required
    def resolve_actuating_device(root, info, id, **kwargs):
        return get_object_or_404(ActuatingDevice,
                                 id=id,
                                 building__user=info.context.user)

    @login_required
    def resolve_control_parameters(root, info, **kwargs):
        building = kwargs.get("building__id")
        if building:
            return ControlParameter.objects.filter(
                building__user=info.context.user, building__id=building)
        return ControlParameter.objects.filter(
            building__user=info.context.user)

    @login_required
    def resolve_control_parameter(root, info, id, **kwargs):
        return get_object_or_404(ControlParameter,
                                 id=id,
                                 building__user=info.context.user)

    @login_required
    def resolve_schedules(root, info, **kwargs):
        ordering = kwargs.get("ordering", "")
        building = kwargs.get("building__id")
        if building:
            query = Schedule.objects.filter(building__user=info.context.user,
                                            building__id=building)
        query = Schedule.objects.filter(building__user=info.context.user)
        if ordering:
            query = query.order_by('time_from')
        return query

    @login_required
    def resolve_schedule(root, info, id, **kwargs):
        return get_object_or_404(Schedule,
                                 id=id,
                                 building__user=info.context.user)

    @login_required
    def resolve_users(root, info, **kwargs):
        return User.objects.all()

    @login_required
    def resolve_user(root, info, id, **kwargs):
        return get_object_or_404(User, id=id)
Esempio n. 23
0
class BookInput(graphene.InputObjectType):
    id = graphene.ID()
    title = graphene.String()
    author = graphene.String()
    year_published = graphene.String()
    review = graphene.Int()
Esempio n. 24
0
 class Arguments:
     id = graphene.ID()
     state = graphene.Boolean()
     state_value = graphene.Boolean()
     light_level = graphene.Int()
     token = graphene.String(required=True)
 class Arguments:
     tournament = graphene.ID(required=True)
     matchup = graphene.ID(required=True)
     side = graphene.Argument(Side, required=True)
     order = graphene.Int(required=True)
     witness = graphene.String(required=True)
Esempio n. 26
0
class ScheduleDeviceStateInput(graphene.InputObjectType):
    schedule = graphene.Int()
    device = graphene.Int()
    state = graphene.Boolean()
    state_value = graphene.Decimal()
    light_level = graphene.Int()
Esempio n. 27
0
class Device(graphene.ObjectType):
    id = graphene.String()
    kind = graphene.String()
    stat = graphene.Int()
    name = graphene.String()
Esempio n. 28
0
class Person(graphene.ObjectType):
    name = graphene.String()
    age = graphene.Int()
Esempio n. 29
0
class OrderItemsInput(graphene.InputObjectType):
    product_id = graphene.ID()
    modification_items = graphene.List(ModificationsItemsOrderInput)
    price = graphene.Int()
    quantity = graphene.Int()
    parent_id = graphene.ID()
Esempio n. 30
0
class Category(CountableDjangoObjectType):
    ancestors = PrefetchingConnectionField(
        lambda: Category, description="List of ancestors of the category."
    )
    products = ChannelContextFilterConnectionField(
        Product,
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned."
        ),
        description="List of products in the category.",
    )
    url = graphene.String(
        description="The storefront's URL for the category.",
        deprecation_reason="This field will be removed after 2020-07-31.",
    )
    children = PrefetchingConnectionField(
        lambda: Category, description="List of children of the category."
    )
    background_image = graphene.Field(
        Image, size=graphene.Int(description="Size of the image.")
    )
    translation = TranslationField(CategoryTranslation, type_name="category")

    class Meta:
        description = (
            "Represents a single category of products. Categories allow to organize "
            "products in a tree-hierarchies which can be used for navigation in the "
            "storefront."
        )
        only_fields = [
            "description",
            "description_json",
            "id",
            "level",
            "name",
            "parent",
            "seo_description",
            "seo_title",
            "slug",
        ]
        interfaces = [relay.Node, ObjectWithMetadata]
        model = models.Category

    @staticmethod
    def resolve_ancestors(root: models.Category, info, **_kwargs):
        return root.get_ancestors()

    @staticmethod
    def resolve_background_image(root: models.Category, info, size=None, **_kwargs):
        if root.background_image:
            return Image.get_adjusted(
                image=root.background_image,
                alt=root.background_image_alt,
                size=size,
                rendition_key_set="background_images",
                info=info,
            )

    @staticmethod
    def resolve_children(root: models.Category, info, **_kwargs):
        return root.children.all()

    @staticmethod
    def resolve_url(root: models.Category, _info):
        return ""

    @staticmethod
    def resolve_products(root: models.Category, info, channel=None, **_kwargs):
        requestor = get_user_or_app_from_context(info.context)
        requestor_has_access_to_all = models.Product.objects.user_has_access_to_all(
            requestor
        )
        tree = root.get_descendants(include_self=True)
        if channel is None and not requestor_has_access_to_all:
            channel = get_default_channel_slug_or_graphql_error()
        qs = models.Product.objects.all()
        if not requestor_has_access_to_all:
            qs = (
                qs.published(channel)
                .annotate_visible_in_listings(channel)
                .exclude(visible_in_listings=False,)
            )
        if channel and requestor_has_access_to_all:
            qs = qs.filter(channel_listings__channel__slug=channel)
        qs = qs.filter(category__in=tree)
        return ChannelQsContext(qs=qs, channel_slug=channel)

    @staticmethod
    def __resolve_reference(root, _info, **_kwargs):
        return graphene.Node.get_node_from_global_id(_info, root.id)