python - 在 Django 中尝试通过电子邮件或用户名登录时显示未定义的路径
问题描述
我正在使用 Django 创建一个登录页面,以通过用户名或电子邮件登录。我启动了一个应用程序用户,在这个应用程序中,我自定义了 users/model.py
class UserProfile(AbstractUser):
pass
在我的 users/views.py 中,我有代码可以读取 input name="username"
from .models import UserProfile
from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
user = UserProfile.objects.get(Q(username=username)) | Q(email=username))
if user.check_password(password):
return user
except Exception as e:
return None
def login(request):
if request.method == "POST":
user_name = request.POST.get('username', '')
password = request.POST.get('password', '')
user = authenticate(username=user_name, password=password)
if user is not None:
auth_login(request,user)
return render(request, 'index.html')
else:
return render(request, 'login.html',{})
elif request.method == 'GET':
return render(request,"login.html",{})
我的模板/login.html
<form action="/login/" method="post" id="jsLoginForm" autocomplete="off">
<input type='hidden' name='csrfmiddlewaretoken' value='mymQDzHWl2REXIfPMg2mJaLqDfaS1sD5' />
<div class="form-group marb20">
<label>Username</label>
<input name="username" id="account_l" type="text" placeholder="username or email" />
</div>
<div class="form-group marb8">
<label>Password</label>
<input name="password" id="password_l" type="password" placeholder="Enter your password" />
</div>
<div class="error btns login-form-tips" id="jsLoginTips"></div>
<div class="auto-box marb38">
<label><input type="checkbox" id="jsAutoLogin"> Auto login</label>
<a class="fr" href="forgetpwd.html">forget pwd?</a>
</div>
<input class="btn btn-green" id="jsLoginBtn" type="submit" value="login > " />
{% csrf_token %}
</form>
在 urls.py
from users.views import login
urlpatterns = [
url('^login/$',login, name='login'),
]
在 settings.py
AUTH_USER_MODEL = 'users.UserProfile'
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
'users.views.CustomBackend',
]
结果,我可以使用用户名和密码登录,它打印:
[03/Feb/2019 23:40:06] "POST /login/ HTTP/1.1" 200 37066 #
但是当我使用电子邮件和密码登录时,我的浏览器没有任何变化。在终端上,它打印:
Not Found: /user/login/
[03/Feb/2019 23:41:30] "POST /user/login/ HTTP/1.1" 404 2213
我不知道这条路径“/user/login/”是从哪里来的,它和之前的“/login/”不同。
已解决:我发现问题是由我从教程中复制的代码引起的,有一个 login.js 包括类似 `$.ajax({ url:"/user/login/",}) 的内容。当我使用电子邮件登录时会发生这种情况。
解决方案
检查您没有在某处使用...
url(r'user/', include(users.urls))
并尝试将{% url ... %}
标签用于您的表单操作属性。
另一方面,我认为您应该尝试将您的CustomBackend
第一个放在列表中:
AUTHENTICATION_BACKENDS = [
'users.views.CustomBackend',
"django.contrib.auth.backends.ModelBackend"
]
您可以从文档中阅读,该顺序很重要:
AUTHENTICATION_BACKENDS 的顺序很重要,所以如果相同的用户名和密码在多个后端有效,Django 将在第一个正匹配时停止处理。
如果后端引发 PermissionDenied 异常,身份验证将立即失败。Django 不会检查后面的后端。
也许默认后端找不到用户(您正在通过电子邮件查找)。
推荐阅读
- android - Android: MVVM and separation of concerns
- java - App container cannot connect to mysql container in the same network
- vb.net - How to make a class library reference another class library that contains just an interface?
- microsoft-graph-api - callRecords change notification with authorization error
- unity3d - Unity 2D 实例化预制件订单
- amazon-web-services - AWS CloudFormation 根据环境设置 EFS ThroughputMode 和 ProvisionedThroughputInMibps 问题
- flutter - 在颤动中缓存“FileImage”
- r - Sum 不计算 dplyr 中带有 summarise 的某些字符向量
- scala - toMap 的隐式转换器
- python - 你能让乌龟成为python的圆心吗?