Django графен с релеем, ограничивающим доступ к запросам на основе ID - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь ограничить запросы одного объекта для пользователя, который их создал.

Models.py

class Env(models.Model):
    name = models.CharField(max_length=50)
    user = models.ForeignKey(
        User, on_delete=models.CASCADE)
    description = TextField()

Schema.py

class EnvNode(DjangoObjectType):
    class Meta:
        model = Env
        filter_fields =  {
            'name': ['iexact'],
            'description': ['exact', 'icontains'],
            }
        interfaces = (relay.Node, )


Query(object):
    env = relay.Node.Field(EnvNode)
    all_envs = DjangoFilterConnectionField(EnvNode)

Я попытался добавить запрос разрешения, но он работал только для запроса "all_env" с фильтром и не работал для запроса одного объекта

def resolve_env(self, info):
    env = Env.objects.filter(user = info.context.user.id)
    if env is not None:
        return env
    else:
        return None

Также попытался добавить метод класса в EnvNode, как рекомендовано здесь, при фильтрации доступа к идентификатору на основе узла :

@classmethod
def get_node(context, cls, id, info):
    try:
        env =  cls._meta.model.objects.get(id = id)
    except cls._meta.model.DoesNotExist:
        return None

    if context.user == env.user:
        return env
    return None

но я получил ошибку:

"message": "get_node() missing 1 required positional argument: 'info'",

1 Ответ

0 голосов
/ 22 августа 2018

Похоже, что документация неверна, также ваши параметры не в правильном порядке для метода get_node .

Для звонка есть только три параметра

  • Первый - ваш DjangoObjectType подкласс: EnvNode
  • Вторым является graphql.execution.base.ResolveInfo , который содержит ссылку на контекст. Вы можете получить пользовательский объект оттуда.
  • Третий фактический id для объекта.

Вы должны написать это так, чтобы ограничение работало:

@classmethod
def get_node(cls, info, id):
    try:
        env = cls._meta.model.objects.get(id=id, user=info.context.user)

    except cls._meta.model.DoesNotExist:
        return None

    return env

Надеюсь, это поможет.

...