【问题标题】:Customize a response from a mutation using django-graphql-auth with graphene使用带有石墨烯的 django-graphql-auth 自定义突变响应
【发布时间】:2021-12-02 00:08:41
【问题描述】:

我在我的 django 项目中使用django-graphql-auth 和石墨烯。 django-graphql-auth 库很好,但它缺少一些文档和自定义示例。我已经在那里发送了这个问题,但 repo 最近似乎没有太多活动(也许是时候替换和使用项目中的另一个包了),所以我会在这里试试运气:

大多数与定制相关的问题都与输入有关。就我而言,我想更改 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(user[0]['id']) 我可以看到正在打印的用户 ID。我的猜测是,在这一行:res = super().mutate(*args, **kwargs) 中,通过调用 Register 上的 mutate 方法,我已经注定要从父方法那里得到响应,无论我接下来做什么。

我也尝试了不同的方法。这个,基于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 解决这个问题,因为我已经用它完成了许多功能,无论是一个好的解决方案还是一个我不在乎的 hack,因为我不会经常面对这种情况.此时我不想替换我的整个身份验证逻辑。我的猜测是这是一件相当简单的事情,但缺乏文档使得这变得困难

【问题讨论】:

    标签: python django django-authentication graphene-django


    【解决方案1】:

    你在正确的轨道上。最简单的解决方案是声明一个额外的整数字段:

    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 的模型或类实例

    【讨论】:

    • 那不起作用...仍然是相同的情况。响应是:{“错误”:[{“消息”:“无”,“位置”:[{“行”:476,“列”:5}],“路径”:[“registerCustom”]}], “数据”:{“注册自定义”:空}}
    • 我觉得没有办法覆盖响应。调用 parent mutate() 意味着来自那里的响应是要扔给用户的响应
    • 这是我们目前用来覆盖响应的。该错误消息看起来像您的代码的其他部分存在与包无关的问题。很可能是语法错误,因为它提供了行号和列号。
    猜你喜欢
    • 2020-09-01
    • 2022-10-25
    • 2017-05-11
    • 2020-05-08
    • 2018-03-22
    • 2017-03-18
    • 2022-01-17
    • 2017-05-13
    • 2020-07-27
    相关资源
    最近更新 更多