Django的新手来自Laravel,在那里设置登录和身份验证要容易得多。也就是说,我正在努力使一个简单的登录页面正常工作,并花了几个晚上使用SO,Django文档和各种教程。对于那些只是试图获取登录页面基础知识的人来说,Django文档似乎没有很好的组织,有点压倒性,而且我遇到的大多数SO答案都是旧的。
我使用的这两个教程并没有让我了解我的目标:
Right way of adding user authentication to Django
How to Use Django's Built-in Login System
使用Python 3.5.2,Django 1.10和PostgreSQL 9.6。在我的设置中,localhost:8000
是登录页面。用户需要先登录才能查看任何内容。我还有应用/home
,/results
等,但现在我只使用/home
。如果他们尝试转到localhost:8000/home
,他们将被路由到登录,这样做会将他们带到http://localhost:8000/?next=/home/
。所以这很有效。
当我输入凭据时,它会一直将我发送到登录屏幕。转到localhost:8000
或/home
只会做同样的事情。似乎不是在验证。数据库凭据是正确的,用户凭据是正确的,并且在python manage.py shell
中与数据库进行通信是正常的。
这是我的简化目录结构:
~/portal-client
project_dir
apps
account
templates
account
login.html
forms.py
urls.py
views.py
home
templates
home
home.html
urls.py
views.py
results
settings.py
urls.py
scripts
manage.py
static
templates
base.html
footer.html
title.html
PROJECT_DIR / settings.py
# INSTALLED_APPS, TEMPLATES, STATIC, DATABASES all correct so just this line added
LOGIN_REDIRECT_URL = 'home'
PROJECT_DIR / urls.py
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth import views as auth_views
from account.forms import LoginForm
urlpatterns = [
url(r'', include('account.urls')),
url(r'^admin/', admin.site.urls),
url(r'^documents/$', include('documents.urls')),
url(r'^help/$', include('help.urls')),
url(r'^home/$', include('home.urls')),
url(r'^results/$', include('results.urls')),
url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
url(r'^login/$', auth_views.login, {'template_name': 'account/login.html', 'authentication_form': LoginForm}, name='login'),
]
主/ views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
# Create your view here.
# The following prohibits access to the website unless authenticated
@login_required(login_url="/")
def home(request):
return render(request, 'home/home.html')
account / urls.py - 编辑
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.user_login, name='user_login'),
]
account / forms.py - 编辑
from django.contrib.auth.forms import AuthenticationForm
from django import forms
# If you don't do this you cannot use Bootstrap CSS
class LoginForm(AuthenticationForm:
username = forms.CharField(max_length=50)
password = forms.CharField(widget=forms.PasswordInput)
def clean_username(self):
username = self.cleaned_data.get("username")
def clean_password(self):
password= self.cleaned_data.get("password")
account / views.py - 编辑
from django.shortcuts import render
from django.contrib.auth import views
from .forms import LoginForm
# Create your view here.
def user_login(request):
form = LoginForm(request.POST or None)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return httpResponseRedirect('/home')
else:
return httpResponseRedirect('/')
context = {
"form" : form
}
return render(request, "account/login.html", context)
帐户/ login.html的
<form class="form-horizontal" role="form" method="POST" action="{% url 'home' %}">
{% csrf_token %}
<div class="form-group">
<label for="email" class="col-md-4 control-label">Username</label>
<div class="col-md-6">
{{ form.username }}
</div>
</div>
<div class="form-group">
<label for="password" class="col-md-4 control-label">Password</label>
<div class="col-md-6">
{{ form.password }}
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Login
</button>
<a class="btn btn-link" href="url('/password/reset')">
Forgot Your Password?
</a>
</div>
</div>
</form>
我认为这就是一切!我提前感谢您的帮助!希望继续将这些应用程序放在一起并通过身份验证。
编辑:
我还没读过的一件事是我是否需要对account/models.py
文件做任何事情。所有客户数据都在默认的auth_user
表中。
另外,想知道django-allauth之类的东西是不是一个好的解决方案。
答案 0 :(得分:2)
Django附带authentication views,如果可能,你应该使用这些,而不是自己编写。
您已在网址格式中包含内置登录视图。
url(r'^login/$', auth_views.login, {'template_name': 'account/login.html'}, name='login'),
因此您不需要user_login
视图,因此我会删除它。我已删除您的自定义身份验证表单,因为它不是必需的。默认身份验证表单已包含用户名和密码字段。您已经破解了clean_
方法,因为您没有返回值。
接下来,在模板中修复表单的action
。目前,您正在将表单数据提交到home
视图。您应该将其发送到login
视图。
<form class="form-horizontal" role="form" method="POST" action="{% url 'login' %}">
最后,我会在您的设置中添加LOGIN_URL = 'login'
,然后您可以将使用login_required
的代码简化为以下内容:
@login_required
def home(request):
...