GraphQL:[Errno 111] 连接被拒绝

Posted

技术标签:

【中文标题】GraphQL:[Errno 111] 连接被拒绝【英文标题】:GraphQL: [Errno 111] Connection refused 【发布时间】:2020-11-22 05:43:41 【问题描述】:

说明

我正在尝试为具有不同类型用户(司机、客户、系统管理员和授权者)的交通系统构建 API。为此,我创建了一个AbstractUser 并为上述所有不同的用户使用继承关系。 为了将 JWT 添加到模型中,我已经阅读了 official tutorial,但是每当我想创建一个像下面这样的新用户时,我都会遇到错误:

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

复制步骤

    这是我的模型:
from django.db import models
from django.contrib.auth.models import AbstractUser


# Create your models here.
class Usermodel(AbstractUser, models.Model):
    phone_no = models.CharField(
        max_length=11,
        blank=True,
        verbose_name="Phone Number"
    )

    USERNAME_FIELD = "username"   # e.g: "username", "email"
    EMAIL_FIELD = "email"         # e.g: "email", "primary_email"
    
    def __str__(self):
        return self.username

    
class Driver(Usermodel, models.Model):
    national_id = models.CharField(
        max_length=10, 
        blank=True, 
        verbose_name="National ID"
    )

    profile_picture = models.ImageField(
        blank=True,
        null=True
    )

    STATUS_CHOICES = [
        ('1', 'Free'),
        ('2', 'Busy')
    ]

    driver_status = models.CharField(
        max_length=1,
        choices=STATUS_CHOICES
    )

    rating = models.FloatField(
        default=-1
    )

    ranking = models.IntegerField(
        default=-1
    )

    class Meta:
        verbose_name = 'Driver'
        verbose_name_plural = 'Drivers'

class Authorizer(Usermodel, models.Model):
    class Meta:
        verbose_name = 'Authorizer'
        verbose_name_plural = 'Authorizers'

class Customer(Usermodel, models.Model):
    class Meta:
        verbose_name = 'Customer'
        verbose_name_plural = 'Customers'

class Administrator(Usermodel, models.Model):
    class Meta:
        verbose_name='Adminsitrator'
        verbose_name_plural='Administrators'
    用户架构
import graphene
from graphene import Mutation, ObjectType, InputObjectType
from .models import Driver, Authorizer, Customer, Administrator
from graphene_django.types import DjangoObjectType


class DriverType(DjangoObjectType):
    class Meta:
        model = Driver

class AuthorizerType(DjangoObjectType):
    class Meta:
        model = Authorizer

class Query(ObjectType):
    driver = graphene.Field(
        DriverType,
        id = graphene.ID()
    )

    authorizer = graphene.Field(
        AuthorizerType,
        id = graphene.ID()
    )

    all_drivers = graphene.List(DriverType)
    all_authorizers = graphene.List(AuthorizerType)

    def resolve_all_drivers(self, info, **kwargs):
        return Driver.objects.all()

    def resolve_driver(self, info, **kwargs):
        id = kwargs.get('id')
        if id is not None:
            return Driver.objects.get(pk=id)

    def resolve_authorizer(self, info, **kwargs):
        id = kwargs.get('id')
        if id is not None:
            return Driver.objects.get(pk=id)

    def resolve_all_authorizers(self, info, **kwargs):
        return Authorizer.objects.all()


class DriverInput(InputObjectType):
    first_name = graphene.String()
    last_name = graphene.String()
    email = graphene.String()
    username = graphene.String()
    phone_no = graphene.String()
    national_id = graphene.String()
    password = graphene.String()


class AuthorizerInput(InputObjectType):
    first_name = graphene.String()
    last_name = graphene.String()
    email = graphene.String()
    username = graphene.String()
    phone_no = graphene.String()
    password = graphene.String()
class CreateDriver(Mutation):
    class Arguments:
        driver_data = DriverInput()
        
    driver = graphene.Field(DriverType)

    def mutate(self, info, driver_data=None):
        driver = Driver(
            first_name=driver_data.first_name,
            last_name=driver_data.last_name,
            email=driver_data.email,
            username=driver_data.username,
            phone_no=driver_data.phone_no,
            national_id=driver_data.national_id,
            password=driver_data.password
        )

        driver.save()

        return CreateDriver(
            driver=driver
        )

class UpdateDriver(Mutation):
    class Arguments:
        id = graphene.ID()
        driver_data = DriverInput()
    
    driver = graphene.Field(DriverType)

    def mutate(self, info, id, driver_data=None):
        #TODO: Error handling if the id not exists
        driver = Driver.objects.get(pk=id)

        driver.first_name = driver_data.first_name
        driver.last_name = driver_data.last_name
        driver.email = driver_data.email
        driver.username = driver_data.username
        driver.phone_no = driver_data.phone_no
        driver.national_id = driver_data.national_id
        driver.password = driver_data.password
        driver.save()

        return UpdateDriver(driver=driver)


class AuthorizerInput(InputObjectType):
    first_name = graphene.String()
    last_name = graphene.String()
    email = graphene.String()
    username = graphene.String()
    phone_no = graphene.String()
    password = graphene.String()

class CreateAuthorizer(Mutation):
    class Arguments:
        authorizer_data = AuthorizerInput()

    authorizer = graphene.Field(AuthorizerInput)

    def mutate(self, info, authorizer_data=None):
        authorizer = Authorizer(
            firstname=authorizer_data.first_name,
            last_name=authorizer_data.last_name,
            email=authorizer_data.email,
            username=authorizer_data.username,
            phone_no=authorizer_data.phone_no,
            password=authorizer_data.password
        )
        authorizer.save()
        return CreateAuthorizer(authorizer=authorizer)

class UpdateAuthorizer(Mutation):
    class Arguments:
        id = graphene.ID()
        authorizer_data = AuthorizerInput()
    
    authorizer = graphene.Field(AuthorizerType)
    
    def mutate(self, info, id, authorizer_data=None):
        authorizer = Authorizer.objects.get(pk=id)
        authorizer.first_name = authorizer_data.first_name
        authorizer.last_name = authorizer_data.last_name
        authorizer.email = authorizer_data.email
        authorizer.username = authorizer_data.username
        authorizer.password = authorizer_data.password
        authorizer.save()

        return UpdateDriver(authorizer=authorizer)

class Mutations(ObjectType):
    create_driver = CreateDriver.Field()
    update_driver = UpdateDriver.Field()

    项目架构
import graphene

from apps.users.schema import Query as user_query
from apps.users.schema import Mutations as user_mutation
from graphql_auth.schema import UserQuery, MeQuery
from graphql_auth import mutations

class AuthMutation(graphene.ObjectType):
   register = mutations.Register.Field()


class Query(user_query, UserQuery, MeQuery):
    pass

class Mutations(user_mutation, AuthMutation):
    pass    

schema = graphene.Schema(
    query=Query,
    mutation=Mutations
)

预期行为

我希望代码运行没有任何问题,但在actual behavior中遇到以下错误

我还有一个问题。正如我已经解释的各种用户和他们的注册,我需要不同的论点。但是在架构中我们只是添加register = mutations.Register.Field(),我怎样才能达到这个目的?

实际行为

要求

aniso8601==7.0.0
asgiref==3.2.10
Django==3.0.8
django-filter==2.3.0
django-graphql-auth==0.3.11
django-graphql-jwt==0.3.0
graphene==2.1.8
graphene-django==2.12.1
graphql-core==2.3.2
graphql-relay==2.0.1
Pillow==7.2.0
pkg-resources==0.0.0
promise==2.3
PyJWT==1.7.1
pytz==2020.1
Rx==1.6.1
singledispatch==3.4.0.3
six==1.15.0
sqlparse==0.3.1
Unidecode==1.1.1

【问题讨论】:

【参考方案1】:

问题1:我希望代码运行没有任何问题,但在实际行为中会遇到以下错误

注意如果不查看您的 settings.py 是如何配置的,回答这个问题会有点困难,但请仔细检查您是否完成了每一步。我也完成了快速入门,但仍然错过了一些地方。

答:确保您的settings.py 配置正确

我遇到了类似的“连接被拒绝”错误,但问题是我的设置没有正确配置。

编辑:在进一步的本地开发和切换个别设置后,我意识到我的“连接被拒绝错误与未配置 EMAIL_BACKEND 有关。它试图连接到任何未运行的 SMTP 服务器。确保您已将 EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" 设置为将此功能记录到您的控制台。

这是我使用的一个草稿项目中的settings.py 的稍微缩写的副本,只是为了确保您已正确配置它:

来源:django-graphql-auth quickstart。

注意:它有点长,请确保一直滚动

# ...


# Application definition

INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    
    # Package apps
    "corsheaders",
    "graphene_django",
    "graphql_jwt.refresh_token.apps.RefreshTokenConfig",
    "graphql_auth",
    "django_filters",

    # Created apps
    "users", # or whatever the name of the app is with your custom users model
]

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

ROOT_URLCONF = "<project_name>.urls"

# TEMPLATES = ...
# WSGI_APPLICATION = ...
# DATABASES = ...

# Ensure that custom user is set
AUTH_USER_MODEL = "users.CustomUser"

# AUTH_PASSWORD_VALIDATORS = ...

# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/

# ...

# Static files (CSS, javascript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
# ...

GRAPHENE = 
    "SCHEMA": "backend.schema.schema",
    "MIDDLEWARE": ["graphql_jwt.middleware.JSONWebTokenMiddleware",],


AUTHENTICATION_BACKENDS = [
    "graphql_jwt.backends.JSONWebTokenBackend",
    "django.contrib.auth.backends.ModelBackend",
    "graphql_auth.backends.GraphQLAuthBackend",
]

GRAPHQL_JWT = 
    "JWT_VERIFY_EXPIRATION": True,
    "JWT_LONG_RUNNING_REFRESH_TOKEN": True,


EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"

问题 2:正如我对各种用户及其注册的解释,我需要不同的论据。但是在 schema 中我们只是添加了 register = mutation.Register.Field(),我怎样才能达到这个目的呢?

答:TLDR - 设置文档的dynamic fields 部分对此进行了说明。

A:演练

第 1 步:确保您的自定义用户模型已设置字段

在我们考虑更新设置之前,请确认您需要设置的自定义字段存在于模型中。例如,如果我想要一个 luck_number 字段,我会添加:

class CustomUser(AbstractUser):
    ...

    luck_number = models.IntegerField()
    ...

然后,您需要确保运行迁移,以便它存在于您的数据库中。 python manage.py makemigrations python manage.py migrate

第2步:将GRAPHQL_AUTH添加到settings.py

在您的设置中,确保设置:

# Rest of your settings ...

GRAPHQL_AUTH = 

第 3 步:添加您的自定义字段并仔细检查您的架构

如果您想在注册时添加要收集的字段,您需要将REGISTER_MUTATION_FIELDS 添加到您的GRAPHQL_AUTH 设置中。所以在将luck_number 添加到我们的register 突变的情况下:

GRAPHQL_AUTH = 
  REGISTER_MUTATION_FIELDS = 
    "email": "String",
    "username": "String",
    "luck_number": "Int",
  

编辑1:添加图片

编辑 2:对我的注册突变错误进行说明

【讨论】:

哇!多么完整的答案。谢谢弗兰克。欢迎来到 *** 人! :) 感谢@MostafaGhadimi,快乐的黑客:)

以上是关于GraphQL:[Errno 111] 连接被拒绝的主要内容,如果未能解决你的问题,请参考以下文章

连接被拒绝 MongoDB errno 111

Python socket.error:[Errno 111] 连接被拒绝

Django- [Errno 111] 使用 smtp 时连接被拒绝

将 Celery 与 SQS 一起使用时 Errno 111 连接被拒绝

无法连接到 amqp://guest:**@127.0.0.1:5672//: [Errno 111] 连接被拒绝

OperationalError:(2003,“无法连接到'localhost'上的MySQL服务器([Errno 111]连接被拒绝)”)[关闭]