如何组合if \ else逻辑中的少数突变以获得'GetOrCreateUser'?

时间:2018-03-14 02:18:48

标签: django graphql graphene-python

我使用VueJS和Django + django-graphql-jwt(返回令牌)。我想使用email \ password字段进行注册和登录。在服务器上,我想检查提供的电子邮件是否已存在 - >使用django-graphql-jwt的变异token_auth = graphql_jwt.ObtainJSONWebToken.Field()返回令牌+消息,否则 - >>使用提供的电子邮件和密码创建一个新用户并返回此用户+消息。

现在我有:

# schema.py

import graphene
import graphql_jwt

from django.contrib.auth import get_user_model
from graphene_django import DjangoObjectType


class UserType(DjangoObjectType):
    class Meta:
        model = get_user_model()


class CreateUser(graphene.Mutation):
    user = graphene.Field(UserType)

    class Arguments:
        password = graphene.String(required=True)
        email = graphene.String(required=True)

    def mutate(self, info, password, email):
        user = get_user_model()(
            username=email.split('@')[0],
            email=email,
        )
        user.set_password(password)
        user.save()

        return CreateUser(user=user)

# Want to combine two mutations here
class GetOrCreateUser(graphene.Mutation):
    user = graphene.Field(UserType)

    class Arguments:
        password = graphene.String(required=True)
        email = graphene.String(required=True)

    def mutate(self, info, password, email):
        # Return token
        if get_user_model().objects.filter(email=email).exists():
            # Just an idea, what I want to get here (to be returned to VueJS)
            return {'token': graphql_jwt.ObtainJSONWebToken.Field(), 'msg': 'Token Generated'}

        # Create new user
        else:
            user = CreateUser(???)
            return {'user': user, 'msg': 'User is Created'}


class Mutation(graphene.ObjectType):
    create_user = CreateUser.Field()
    get_or_create_user = GetOrCreateUser.Field()

我尝试了不同的变体,但似乎我不完全理解图形的工作流程或\以及魔术Graphene做了什么(其文档没有提供信息)。

任何人都可以告诉我,如何在if \ else块中重新使用已创建的代码(CreateUser class和graphql_jwt.ObtainJSONWebToken.Field())?

3 个答案:

答案 0 :(得分:3)

django-graphql-auth完全满足您的需求。

它扩展了django-graphql-jwt以处理所有与用户帐户有关的操作。

这是docs的注册突变:

mutation {
  register(
    email:"skywalker@email.com",
    username:"skywalker",
    password1: "supersecretpassword",
    password2:"supersecretpassword"
  ) {
    success,
    errors,
    token,
    refreshToken
  }
}

它已经从django-graphql-jwt返回令牌和刷新令牌。

比起docs,您可以用来登录:

mutation {
  tokenAuth(
    # username or email
    email: "skywalker@email.com"
    password: "supersecretpassword"
  ) {
    success,
    errors,
    token,
    refreshToken,
    unarchiving,
    user {
      id,
      username
    }
  }
}

PS:我是作者

答案 1 :(得分:0)

您可以创建一个函数并在两个突变中使用它:

def get_or_create_user(password, email):
    if get_user_model().objects.filter(email=email).exists():
        return ('user or token or other data that you need in'
                'mutation, this is not mutation return value')
               # {'token': graphql_jwt.ObtainJSONWebToken.Field(),
               # 'msg': 'Token Generated'}

    # Create new user
    else:
        user = get_user_model()(
            username=email.split('@')[0],
            email=email,
        )
        user.set_password(password)
        user.save()

        return ('user or token or other data that you need in'
                'mutation, this is not mutation return value')
               # {'user': user,
               # 'msg': 'User is Created'}

答案 2 :(得分:0)

  1. 我没有找到如何从变异中调用变异(我如何从class CreateUser调用class GetOrCreateUser,所以我决定将CreateUser整合到GetOrCreateUser )。

  2. 我没有找到,如何通过代码调用graphql_jwt(示例来自graphene doc

    schema = graphene.Schema(...)
    result = schema.execute('{ name }')
    

    所以我决定直接通过Python而不是Python \ GraphQL来获取令牌。

  3. 以下是完整代码:

    # schema.py (the root one)
    import graphene
    import graphql_jwt
    import apps.users.schema
    
    
    class Query(apps.users.schema.Query, graphene.ObjectType):
        pass
    
    
    class Mutation(apps.users.schema.Mutation, graphene.ObjectType):
        verify_token = graphql_jwt.Verify.Field()
        refresh_token = graphql_jwt.Refresh.Field()
    
    
    schema = graphene.Schema(query=Query, mutation=Mutation)
    

    # users/schema.py
    import graphene
    
    from django.contrib.auth import get_user_model
    from graphene_django import DjangoObjectType
    from graphql_jwt.shortcuts import get_token
    
    
    class UserType(DjangoObjectType):
        class Meta:
            model = get_user_model()
    
    
    class GetOrCreateUser(graphene.Mutation):
        """
        mutation {
          getOrCreateUser(email: "test@domain.com", password: "YourPass") {
            token
            user {
              id
              email
              isActive
            }
          }
        }
        """
    
        user = graphene.Field(UserType)
        token = graphene.String()
    
        class Arguments:
            password = graphene.String(required=True)
            email = graphene.String(required=True)
    
        def mutate(self, info, password, email):
            token = ''
    
            # Return token
            if get_user_model().objects.filter(email=email).exists():
                user = get_user_model().objects.get(email=email)
                token = get_token(user)
    
            # Create new user
            else:
                user = get_user_model()(
                    username=email.split('@')[0],
                    email=email,
                )
                user.set_password(password)
                user.save()
    
            return GetOrCreateUser(user=user, token=token)
    
    
    class Query(graphene.ObjectType):
        users = graphene.List(UserType)
    
        def resolve_users(self, info):
            return get_user_model().objects.all()
    

    FrontEnd可以通过选中token字段来定义状态。如果为空,则创建用户,如果存在,则表示存在并且刚刚登录。