Настройка ответа от мутации с помощью django-graphql-auth с graphene

Я использую django-graphql-auth и graphene в своем проекте django. Библиотека django-graphql-auth хороша, но ей немного не хватает документации и примеров настройки. Я уже отправил этот вопрос туда, но репо, кажется, не получает большой активности в последнее время (возможно, пришло время заменить и использовать другой пакет в проекте), поэтому я попытаю счастья здесь:

большинство вопросов, связанных с настройкой, касаются входов. В моем случае я хотел бы изменить вывод мутации Register, поскольку мне нужен id пользователя, созданного в ответе

На данный момент мне удалось создать новую пользовательскую мутацию, которая наследует регистр, поэтому я могу добавить логику для захвата созданного пользователя:

class RegisterCustom(mutations.Register):
    response = graphene.Field(RegisterResponseType)

    @classmethod
    def mutate(cls, *args, **kwargs):
        try:
            res = super().mutate(*args, **kwargs)
            if res.success:
                user = get_user_model().objects.order_by('-date_joined')[:1]

            return RegisterCustom(success=True, error="", user_id=user[0]['id'])
        except Exception:
            raise Exception(res.errors)

Однако отдача не та, которую я ожидаю

{
  "errors": [
    {
      "message": "None",
      "locations": [
        {
          "line": 472,
          "column": 5
        }
      ],
      "path": [
        "registerCustom"
      ]
    }
  ],
  "data": {
    "registerCustom": null
  }
}

Если я добавлю print прямо перед return, скажем, print(user[0]['id']), я увижу, что выводится id пользователя. Я предполагаю, что в этой строке: res = super().mutate(*args, **kwargs), вызывая метод mutate на Register, я уже обречен получить ответ от родительского метода, что бы я ни делал дальше.

Я также попробовал другой подход. Этот основан на примере из graphene docs :

class RegisterCustom(mutations.Register):
        

    Output = RegisterResponseType

    @classmethod
    def mutate(cls, *args, **kwargs):
        try:
            res = super().mutate(*args, **kwargs)

            if res.success:
                user = get_user_model().objects.order_by('-date_joined')[:1]
                return RegisterResponseType(sucess=True, error="", user_id=user[0]['id'])
        except Exception:
            raise Exception(res.errors)

Также пробовал этот способ, без успеха

class RegisterCustom(mutations.Register):
    response = graphene.Field(RegisterResponseType)

    @classmethod
    def mutate(cls, *args, **kwargs):
        try:
            res = super().mutate(*args, **kwargs)
            if res.success:
                user = get_user_model().objects.order_by('-date_joined')[:1]
                response = {'success': True, 'error': '', 'user_id': user[0]['id']}
                return RegisterCustom(response=response)
        except Exception:
            raise Exception(res.errors)

Идеально я хочу решить это с помощью django-graphql-auth, так как у меня уже есть много функций, сделанных с его помощью, будь это хорошее решение или хак, мне все равно, так как я не буду сталкиваться с этим сценарием слишком часто. Я не хочу заменять всю логику аутентификации на данном этапе. Я думаю, что это довольно просто сделать, но отсутствие документации затрудняет это

Вы на правильном пути. Самое простое решение - объявить дополнительное целочисленное поле:

class RegisterCustom(mutations.Register):
    user_id = graphene.Int()

    @classmethod
    def mutate(cls, *args, **kwargs):
        try:
            email = kwargs.get("email")
            UserStatus.clean_email(email)

            res = super().mutate(*args, **kwargs)
            user = get_user_model().objects.filter(email=email).first()

            return cls(
                success=res.success,
                errors=res.errors,
                token=res.token,
                refresh_token=res.refresh_token,
                user_id=user.pk if user else None,
            )

        except Exception:
            raise Exception(res.errors)

Вы можете, однако, вернуть RegisterResponseType, но не забудьте также изменить тип соответствующим образом

class RegisterCustom(mutations.Register):
    response = graphene.Field(RegisterResponseType)

    @classmethod
    def mutate(cls, *args, **kwargs):
        try:
            ... 
            return cls(
                success=res.success,
                errors=res.errors,
                token=res.token,
                refresh_token=res.refresh_token,
                response=response,
            )
        except Exception:
            ...

и что response является моделью или экземпляром класса, который соответствует RegisterResponseType

Вернуться на верх