Расширение аргументов запроса в graphene / graphene_django

Как добавить неполевые аргументы в запрос GraphQL в графене? Вот пример использования. Я бы хотел уметь:

{
  hsv(h: 40, s: 128, v: 54) {
    r
    g
    b
    name
}

с этой моделью Django:

from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator,

class Color(models.Model):
    name = models.CharField(
        "name",
        max_length=24,
        null=False, blank=False)
    r = models.IntegerField(
        "red", null=False, blank=False,
        validators=[MinValueValidator(0), MinValueValidator(255)]
    )

    g = models.IntegerField(
        "green", null=False, blank=False,
        validators=[MinValueValidator(0), MinValueValidator(255)]
    )

    b = models.IntegerField(
        "blue", null=False, blank=False,
        validators=[MinValueValidator(0), MinValueValidator(255)]
    )

и этот тип объекта GraphQL и основанный на нем запрос:

from graphene import ObjectType, IntegerField, Field, relay
from graphene_django import DjangoObjectType

from .django import Color
from colorsys import hsv_to_rgb

class ColorNode(DjangoObjectType):
    r = IntegerField()
    g = IntegerField()
    b = IntegerField()

    class Meta:
        model = Color

class Query(ObjectType):
    rgb = relay.node.Field(ColorNode)
    hsv = relay.node.Field(ColorNode)
    named = relay.node.Field(ColorNode)

    def resolve_rgb(self, args, context, info):
        if not all(map(lambda x: x in args, ['r', 'g', 'b'])):
            # Arguments missing
            return None
        return Color.objects.get(**args)

    def resolve_hsv(self, args, context, info):
        if not all(map(lambda x: x in args, ['h', 's', 'v'])):
            # Arguments missing
            return None

        r, g, b = hsv_to_rgb(args['h'], args['s'], args['v'])
        return Color.objects.get(r=r, g=g, b=b)

    def resolve_named(self, args, context, info):
        if not 'name' in args:
            # Arguments missing
            return None
        return Color.objects.get(name=args['name'])

Это не удается, потому что аргументы не принимаются. Что мне не хватает?


person Scott Deerwester    schedule 09.02.2017    source источник
comment
(В ответ на комментарий об использовании Connection и ConnectionField, который теперь кажется удаленным.) Не могли бы вы составить быстрый ответ, показывающий, как это работает? Я просмотрел документы по реле и не понимаю, как передать значения ConnectionField в запрос.   -  person Scott Deerwester    schedule 09.02.2017


Ответы (1)


Ответ оказывается простым. Чтобы добавить аргументы в преобразователь, объявите аргументы в конструкторе поля, например:

rgb = relay.node.Field(ColorNode,
    r=graphene.String(),
    g=graphene.String(),
    b=graphene.String())
hsv = relay.node.Field(ColorNode,
    h=graphene.String(),
    s=graphene.String(),
    v=graphene.String()))
named = relay.node.Field(ColorNode,
    name=graphene.String())

Затем аргументы могут быть включены в запрос, как показано выше.

person Scott Deerwester    schedule 10.02.2017
comment
Изменили ли они способ работы? Кажется, это больше не работает (когда я распечатываю схему, у меня остается только customer(id: ID!): Customer). Хотя я создал свое поле с помощью graphene.relay.Node.Field(Customer, login=graphene.String()). Я что-то упускаю? (версия графена: 2.1.8). - person cglacet; 01.12.2019
comment
в коде выглядит так он должен работать, не знаю, почему это не так. - person cglacet; 01.12.2019
comment
у меня тоже не работает в реле, только в родных графеновых полях. эта ссылка, которую вы показываете, кажется последней. - person cryptojesus; 30.03.2020
comment
Здесь может возникнуть некоторая путаница в отношении разницы между relay.Node.Field и relay.node.Field. Насколько я могу судить, первое - это поле Relay, которое не обрабатывает лишние аргументы, а второе - простое старое поле, которое имеет (но не имеет идентификатора реле). - person Craig Anderson; 08.02.2021