如何在 Graphene Python 突变中设置 cookies?

How to set cookies in Graphene Python mutation?

Graphene Python 中,当无法访问 HttpResponse 对象来设置 cookie 时,应该如何在 schema.py 中设置 cookie?

我当前的实现是通过捕获 data.operationName 覆盖 GraphQLView 的调度方法来设置 cookie。这涉及对我需要设置 cookie 的操作名称/突变进行硬编码。

在views.py中:

class PrivateGraphQLView(GraphQLView):
    data = self.parse_body(request)
    operation_name = data.get('operationName')
    # hard-coding === not pretty.
    if operation_name in ['loginUser', 'createUser']:
        ...
        response.set_cookie(...)
    return response

是否有更简洁的方法来为特定石墨烯 Python 突变设置 cookie?

最后通过中间件设置 cookie。

class CookieMiddleware(object):

    def resolve(self, next, root, args, context, info):
        """
        Set cookies based on the name/type of the GraphQL operation
        """

        # set cookie here and pass to dispatch method later to set in response
        ...

在自定义 graphql 视图中,views.py,覆盖调度方法以读取 cookie 并设置它。

class MyCustomGraphQLView(GraphQLView):  

    def dispatch(self, request, *args, **kwargs):
        response = super(MyCustomGraphQLView, self).dispatch(request, *args, **kwargs)
        # Set response cookies defined in middleware
        if response.status_code == 200:
            try:
                response_cookies = getattr(request, CookieMiddleware.MIDDLEWARE_COOKIES)
            except:
                pass
            else:
                for cookie in response_cookies:
                    response.set_cookie(cookie.get('key'), cookie.get('value'), **cookie.get('kwargs'))
        return response

我遇到了类似的问题。我需要能够在突变中设置语言 cookie,并最终将请求实例与自定义中间件结合使用。

这是简化的代码:

class SetLanguage(Mutation):
    class Arguments:
        code = String(required=True)

    ok = Field(Boolean)
    language = Field(LanguageType)

    def mutate(root, info, code):
        info.context.set_language_cookie = code
        return SetLanguage(ok=True, language=code)

突变无权访问响应,因此它暂时将值存储在请求实例上。创建响应后,自定义中间件将检索它并设置 cookie:

class LanguageConfigMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)

        if code := getattr(request, "set_language_cookie", None):
            response.set_cookie(settings.LANGUAGE_COOKIE_NAME, code)

        return response