我尝试使用Django 1.11中的自定义身份验证后端来构建功能(使用用户的电子邮件登录,而不是使用用户名的常规登录。并且用户名和useremail都保存在数据库的同一用户对象中)。
使用以下代码,我可以成功使用用户名(我以HTML表单的用户名空白输入正确的用户名值)和密码作为一对登录。但是,当我使用HTML表单输入中的电子邮件值时,则会在后台调试窗口中弹出错误,如下所示:
错误“未找到:/ user / login /;
“ POST /用户/登录/ HTTP / 1.1” 404“
我很好奇,因为整个urls.py和users.views.py根本没有“用户/登录”。它是怎么来的?
在寻求帮助之前,我先查看了Django官方doc(版本1.11)和堆栈溢出中的其他建议性注释,但仍对此没有适当的答案。
希望你们能救我出来并提出您的想法。
顺便说一句,我还检查了1.11 Django Docs,它说 “
Do not forget to test for the is_active attribute of the user in your own backend permission methods.
Changed in Django 1.10:
In older versions, the ModelBackend allowed inactive users to authenticate.
因此,我曾经尝试根据“ is_acitve”检查来解决此错误,但是不幸的是,我还没有解决它。
-更新:在MySQL数据库中,我注意到当前用户对象具有字段
(is_staff =1; is_active=1)
但是我不知道如何使用信息来解决我当前的问题。
我在Pycharm IDE,Django1.11,py 3.6,mysql5.7(作为用于保存用户表的数据库)中将其用完
在setting.py中,
AUTHENTICATION_BACKENDS = ( # 'django.contrib.auth.backends.ModelBackend', 'django.contrib.auth.backends.ModelBackend', ) INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'users', 'courses', 'organization', 'operation', 'xadmin', 'crispy_forms', 'DjangoUeditor', ] AUTH_USER_MODEL = "users.UserProfile" TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', 'django.template.context_processors.media', ], }, }, ]
在urls.py中,
from django.conf.urls import url, include from django.contrib import admin from django.views.generic import TemplateView import xadmin from .settings import MEDIA_ROOT from django.views.static import serve from users. views import user_login urlpatterns = [ url(r'^xadmin/', xadmin.site.urls), url(r'^media/(?P.*)$', serve, {"document_root": MEDIA_ROOT}), url('^$', TemplateView.as_view(template_name='index.html'), name='index'), url('^login/$', user_login, name='login'), name='upload'), ]
在users.views.py中,
from django.shortcuts import render from django.contrib.auth import authenticate, login from django.contrib.auth.backends import ModelBackend from django.db.models import Q from .models import UserProfile 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 UserProfile.DoesNotExist as e: return None def user_login(request): if request.method == "POST": user_name = request.POST.get("username", "") pass_word = request.POST.get("password", "") user = authenticate(username=user_name, password=pass_word) if user is not None: login(request, user) return render(request, "index.html") else: return render(request, "login.html", {"msg": "name or password erro!"}) 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>your name</label>
input name="username" id="account_l" type="text" placeholder="手机号/邮箱" />
/div>
div class="form-group marb8">
label>your password</label>
input name="password" id="password_l" type="password" placeholder="please input your password" />
/div>
div class="error btns login-form-tips" id="jsLoginTips">{{ msg }}</div>
div class="auto-box marb38">
label><input type="checkbox" id="jsAutoLogin"> instant login </label>
a class="fr" href="forgetpwd.html">forget your password?</a>
/div>
input class="btn btn-green" id="jsLoginBtn" type="submit" value="instant login > " />
{% csrf_token %}
/form>
]
在理想情况下,以HTML格式输入正确的用户的电子邮件值和密码值后,也请按“登录”按钮,然后我假定我可以使用以下命令登录到index.html与要验证的用户名和密码相同。
答案 0 :(得分:0)
我猜不确定这里可能出什么问题,其中一个视图受decorator或LoginRequiredMixin保护,该视图可能配置了user/login
路由。
您还缺少的一件事是将CustomBackend添加到您的AUTHENTICATION_BACKENDS
AUTHENTICATION_BACKENDS = (
'your_app.views.CustomBackend',
'django.contrib.auth.backends.ModelBackend',
)
也在视图中,而不是在登录成功后呈现index.html
,而是重定向到主页:
def user_login(request):
if request.method == "POST":
user_name = request.POST.get("username", "")
pass_word = request.POST.get("password", "")
user = authenticate(username=user_name, password=pass_word)
if user is not None:
login(request, user)
return redirect(reverse('index'))
else:
return render(request, "login.html", {"msg": "name or password erro!"})
elif request.method == "GET":
return render(request, "login.html", {})
另外,像这样更新login_html
:
<form action="{% url 'login' %}" method="post" id="jsLoginForm" autocomplete="off">