首页 > 解决方案 > 在 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/",}) 的内容。当我使用电子邮件登录时会发生这种情况。

标签: pythondjango

解决方案


检查您没有在某处使用...

url(r'user/',  include(users.urls))

并尝试将{% url ... %}标签用于您的表单操作属性。

另一方面,我认为您应该尝试将您的CustomBackend第一个放在列表中:

AUTHENTICATION_BACKENDS = [
    'users.views.CustomBackend',
    "django.contrib.auth.backends.ModelBackend"
]

您可以从文档中阅读,该顺序很重要:

AUTHENTICATION_BACKENDS 的顺序很重要,所以如果相同的用户名和密码在多个后端有效,Django 将在第一个正匹配时停止处理。

如果后端引发 PermissionDenied 异常,身份验证将立即失败。Django 不会检查后面的后端。

也许默认后端找不到用户(您正在通过电子邮件查找)。


推荐阅读