Django REST EmailAddress 匹配查询不存在
Posted
技术标签:
【中文标题】Django REST EmailAddress 匹配查询不存在【英文标题】:Django REST EmailAddress matching query does not exist 【发布时间】:2020-01-26 10:49:36 【问题描述】:我正在使用 django rest-auth
和 allauth
对用户进行身份验证。成功注册并验证电子邮件后,我实现了一个登录视图,其子类rest-auth.views.LoginView
如下所示:
class ThLoginView(LoginView):
def get(self, request):
form = CustomUserLoginForm()
return render(request, "users/login.html", context="form": form)
用我自己的形式:
class CustomUserLoginForm(AuthenticationForm):
class Meta:
model = CustomUser
fields = ('email',)
问题是当我登录时出现此错误:
DoesNotExist at /users/login/
EmailAddress matching query does not exist.
我改变的另一件重要的事情是我使用电子邮件作为注册/登录而不是用户名:
Settings.py
>ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_UNIQUE_EMAIL = True
我的user
模型会覆盖AbstractBaseUser
,如下所示:
class CustomUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
name = models.CharField(max_length=254, null=True, blank=True)
username = models.CharField(max_length=254, blank=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def __str__(self):
return self.email
该错误似乎表明搜索算法没有在正确的位置查找电子邮件。肯定会输入用户的电子邮件,因为我可以在管理页面中监督这一点。为什么会出现这个错误?
注意:如果我使用 REST 可浏览 API 也会出现此错误,因此它没有链接到我的表单和模板。
完整的回溯
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/users/login/
Django Version: 2.2.5
Python Version: 3.7.3
Installed Applications:
['users.apps.UsersConfig',
'home.apps.HomeConfig',
'main.apps.MainConfig',
'rest_framework',
'rest_framework.authtoken',
'rest_auth',
'rest_auth.registration',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'allauth',
'allauth.account',
'allauth.socialaccount.providers.github',
'allauth.socialaccount',
'allauth.socialaccount.providers.facebook']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback:
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/core/handlers/exception.py" in inner
34. response = get_response(request)
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/core/handlers/base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/views/generic/base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/utils/decorators.py" in _wrapper
45. return bound_method(*args, **kwargs)
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
76. return view(request, *args, **kwargs)
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_auth/views.py" in dispatch
49. return super(LoginView, self).dispatch(*args, **kwargs)
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_framework/views.py" in dispatch
505. response = self.handle_exception(exc)
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_framework/views.py" in handle_exception
465. self.raise_uncaught_exception(exc)
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_framework/views.py" in raise_uncaught_exception
476. raise exc
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_framework/views.py" in dispatch
502. response = handler(request, *args, **kwargs)
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_auth/views.py" in post
103. self.serializer.is_valid(raise_exception=True)
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_framework/serializers.py" in is_valid
235. self._validated_data = self.run_validation(self.initial_data)
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_framework/serializers.py" in run_validation
433. value = self.validate(value)
File "/Users/ba/venv/project/lib/python3.7/site-packages/rest_auth/serializers.py" in validate
108. email_address = user.emailaddress_set.get(email=user.email)
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/db/models/manager.py" in manager_method
82. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/ba/venv/project/lib/python3.7/site-packages/django/db/models/query.py" in get
408. self.model._meta.object_name
Exception Type: DoesNotExist at /users/login/
Exception Value: EmailAddress matching query does not exist.
【问题讨论】:
请显示您的完整回溯。 @DanielRoseman 添加了完整的回溯 这似乎根本没有使用您的 LoginView。您确定您已正确配置网址吗?/users/login/
使用的是ThLoginView
,它是LoginView
的子类:path('login/', views.ThLoginView.as_view(), name='rest_logout'),
我不明白你在这里做什么。 rest_auth 不使用表单,它使用序列化程序,并且您还没有自定义它将使用什么序列化程序。你的 AUTH_USER_MODEL 设置是什么?
【参考方案1】:
我希望您可以通过在电子邮件地址模型中创建用户来提供用户 ID、电子邮件并将已验证和主要布尔字段设置为 true 来解决此问题;它为我解决了这个问题
【讨论】:
【参考方案2】:我在处理自定义用户模型时遇到了同样的问题。原因是我首先使用默认的 django 用户模型在控制台上运行了 python manage.py makemigrations
和 python manage.py migrate
。后来,我实现了我的自定义用户模型并进行了迁移。
Django documentation 详细描述了挑战:
在创建数据库表之后更改 AUTH_USER_MODEL 要困难得多,因为它会影响例如外键和多对多关系。
此更改无法自动完成,需要手动修复架构、从旧用户表中移动数据,并且可能需要手动重新应用一些迁移。有关步骤的概要,请参见 #25313。
如果可以的话,我建议从一个新数据库开始。这就是我解决这个问题的方法。否则请尝试关注此tutorial 或此tutorial
【讨论】:
【参考方案3】:我遇到了同样的问题,很可能您以错误的方式阅读令牌。对于我的情况,我使用 username 用户 id ,通过电子邮件获取值。
就这样吧
payload = jwt.decode(token, settings.SECRET_KEY, algorithms='HS256')
user = User.objects.get(id=payload['user_id'])
【讨论】:
【参考方案4】:您收到此错误是因为您用于登录的电子邮件地址在数据库表帐户电子邮件地址中不存在。 Dj-rest-auth
或 Django-rest-auth
包为电子邮件地址创建一个表以跟踪经过验证的用户。
当您尝试使用通过manage.py
命令(例如manage.py createsuperuser
)创建的用户登录时,您可能会遇到此错误。基本上,从 django 管理控制台或管理命令创建的用户不会在电子邮件地址表中创建条目。
要修复此错误,您可能需要在管理控制台中的Accounts> Email Addresses
下创建一个新条目,或在管理控制台中从Authentication and authorization> Users
中删除用户,然后使用 django-rest-auth API 端点重新注册(它将自动添加此电子邮件地址表中的条目)。
【讨论】:
以上是关于Django REST EmailAddress 匹配查询不存在的主要内容,如果未能解决你的问题,请参考以下文章
带有 django-rest-auth 和 django-rest-knox 的 AttributeError - 令牌序列化器
为啥 django-rest-framework 不显示 OneToOneField 数据 - django
Django + AngularJS:没有使用普通 URL 和视图的 Django REST 框架的类 REST 端点?
Django Rest Framework 和 django Rest Framework simplejwt 两因素身份验证