GraphQL:[Errno 111] 连接被拒绝
GraphQL: [Errno 111] Connection refused
描述
我正在尝试为具有不同类型用户(Driver、客户、系统管理员和授权者)的交通系统构建一个 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:我希望代码 运行 没有任何问题,但在实际行为中遇到以下错误
N.B. It's going to be a little difficult to answer this without seeing how your settings.py
is configured, but double-check that you went through every step. I went through the quickstart too but still missed a few spots.
答:确保您的 settings.py
配置正确
我 运行 遇到类似的“连接被拒绝”错误,但问题是我的设置配置不正确。
Edit: After further local development and toggling with individual settings, I realized that my "Connection refused error was related to not having EMAIL_BACKEND
configured. It was trying to connect to any SMTP server that wasn't running. Make sure you have EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
set to log this functionality to your console.
这是我的 settings.py
的一个略微缩略的副本,来自我正在使用的一个临时项目,只是为了确保您已正确配置它:
来源:django-graphql-auth quickstart.
N.B.: 有点长,一定要一直翻过去
# ...
# 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 = mutations.Register.Field(),我怎样才能达到这个目的?
答:TLDR - 这在设置文档的 dynamic fields 部分有解释。
答:演练
第 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 步:添加您的自定义字段和double-check您的架构
如果您想添加在注册时收集的字段,您需要将 REGISTER_MUTATION_FIELDS
添加到您的 GRAPHQL_AUTH
设置中。因此,在将 luck_number
添加到我们的 register
突变的情况下:
GRAPHQL_AUTH = {
REGISTER_MUTATION_FIELDS = {
"email": "String",
"username": "String",
"luck_number": "Int",
}
}
编辑 1:添加图像
编辑 2:对我的寄存器突变错误进行澄清
描述
我正在尝试为具有不同类型用户(Driver、客户、系统管理员和授权者)的交通系统构建一个 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:我希望代码 运行 没有任何问题,但在实际行为中遇到以下错误
N.B. It's going to be a little difficult to answer this without seeing how your
settings.py
is configured, but double-check that you went through every step. I went through the quickstart too but still missed a few spots.
答:确保您的 settings.py
配置正确
我 运行 遇到类似的“连接被拒绝”错误,但问题是我的设置配置不正确。
Edit: After further local development and toggling with individual settings, I realized that my "Connection refused error was related to not having
EMAIL_BACKEND
configured. It was trying to connect to any SMTP server that wasn't running. Make sure you haveEMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend"
set to log this functionality to your console.
这是我的 settings.py
的一个略微缩略的副本,来自我正在使用的一个临时项目,只是为了确保您已正确配置它:
来源:django-graphql-auth quickstart.
N.B.: 有点长,一定要一直翻过去
# ...
# 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 = mutations.Register.Field(),我怎样才能达到这个目的?
答:TLDR - 这在设置文档的 dynamic fields 部分有解释。
答:演练
第 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 步:添加您的自定义字段和double-check您的架构
如果您想添加在注册时收集的字段,您需要将 REGISTER_MUTATION_FIELDS
添加到您的 GRAPHQL_AUTH
设置中。因此,在将 luck_number
添加到我们的 register
突变的情况下:
GRAPHQL_AUTH = {
REGISTER_MUTATION_FIELDS = {
"email": "String",
"username": "String",
"luck_number": "Int",
}
}
编辑 1:添加图像
编辑 2:对我的寄存器突变错误进行澄清