之前构造用户登录系统都是直接调用session来判断用户是否登陆/注销,用自定义model存储用户信息,其实系统自带了auth模块用于登陆系统的构建。
User是auth模块自带的用户数据模型,包含账户/密码/邮箱等多个字段,因此无需自定义model存储用户信息。
User详细属性设置可参考http://python.usyiyi.cn/translate/django_182/ref/contrib/auth.html#django.contrib.auth.models.User
User属性如下:
username:字符串类型。必填。30个字符以内。
first_name:字符串类型。可选。30个字符以内。
last_name:字符串类型。可选。30个字符以内。
email:可选。
password:明文密码的hash或者是某种元数据。该属性不应该直接赋值明文密码,而应该通过set_password()方法进行赋值。
is_staff:Boolean类型。用这个来判断是否用户可以登录进入admin site。
is_active:Boolean类型。用来判断该用户是否是可用激活状态。在删除一个帐户的时候,可以选择将这个属性置为False,而不是真正删除。这样如果应用有外键引用到这个用户,外键就不会被破坏。
is_superuser:Boolean类型。该属性用来表示该用户拥有所有的许可,而无需明确的赋予给他。
last_login:datetime类型。最近一次登陆时间。
date_joined:datetime类型。创建时间。
除了这些属性,还可以使用UserProfile存储用户的额外信息。简单实用方法见http://www.cnblogs.com/esperyong/archive/2012/12/20/2826302.html
创建用户:
from django.contrib.auth.models import User
user = User.objects.create_user(username, email, password)
user.save()
auth模块中User表的存储并非明文存储。
修改密码:
from django.contrib.auth.models import User
u = User.objects.get(username='john')
u.set_password('new password')
u.save()
auth模块提供authenticate(username=username, password=password)函数判断用户是否已经注册,提供login(request, user)函数进行登陆,提供logout(request)注销。
账户密码验证:
from django.contrib.auth import authenticate
user = authenticate(username='john', password='secret')
if user is not None:
# the password verified for the user
if user.is_active:
print("User is valid, active and authenticated")
else:
print("The password is valid, but the account has been disabled!")
else:
# the authentication system was unable to verify the username and password
print("The username and password were incorrect.")
如果密码对于给定的用户名有效它将返回一个User对象。如果密码无效,authenticate()返回None。
结合login进行用户登录,login()使用Django的会话框架来将用户的ID保存在会话中。
from django.contrib.auth import authenticate, login
def myLoginview(request):
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
# Redirect to a success page.
else:
# Return a 'disabled account' error message
...
else:
# Return an 'invalid login' error message.
用户注销。注意,即使用户没有登入,logout()也不会抛出任何错误。当你调用logout()时,当前请求的会话数据将被完全清除。所有存在的数据都将清除。
from django.contrib.auth import logout
def logout_view(request):
logout(request)
# Redirect to a success page.
只允许已登陆用户访问,在视图函数开始加入验证
from django.http import HttpResponseRedirect
def my_view(request):
if not request.user.is_authenticated():
return HttpResponseRedirect('/')
Django在模板中提供了user和perms可以直接使用,如下
{% if user.is_authenticated %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %}
<p>Welcome, new user. Please log in.</p>
{% endif %}
权限和用户组部分,博客http://www.cnblogs.com/esperyong/archive/2012/12/20/2826690.html和 http://djangobook.py3k.cn/2.0/chapter14/写的很好。
############################################################################################################
#################################################登陆验证系统示例#############################################
############################################################################################################
urls.py
from django.conf.urls import url
from django.contrib import admin
from account import views as account_views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^home/', account_views.home, name='home'),
url(r'^register/', account_views.register, name='register'),
url(r'^login/', account_views.login, name='login'),
url(r'^logout/', account_views.logout, name='logout'),
]
views.py
from django.shortcuts import render
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from .forms import LoginForm
from .forms import RigsterForm
# Create your views here.
def home(request):
return render(request, 'account/home.html')
def register(request):
if request.method == 'POST':
form = RigsterForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
email = form.cleaned_data['email']
user = User.objects.create_user(username, email, password)
user.save()
return HttpResponseRedirect('/home')
else:
return HttpResponse('输入格式错误')
else:
form = RigsterForm()
return render(request, 'account/register.html',{'form':form})
def login(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user and user.is_active:
auth_login(request, user)
return HttpResponseRedirect('/home')
else:
return HttpResponse('账号或用户名错误')
else:
form = LoginForm()
return render(request, 'account/login.html',{'form':form})
def logout(request):
auth_logout(request)
return HttpResponseRedirect('/home')
home.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
{%if user.is_authenticated%}
<p>欢迎您,{{user.username}}</p>
<p><a href="/logout">退出</a></p>
{%else%}
<p>欢迎您,请登录。</p>
<p><a href="/login">登陆</a></p>
<p><a href="/register">注册</a></p>
{%endif%}
</body>
</html>
register.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<div id="login">
<h2>用户注册</h2>
<form method='post'>
{% csrf_token %}
<p><label>账户: </label>{{form.username}}</p>
<p><label>邮箱: </label>{{form.email}}</p>
<p><label>密码: </label>{{form.password}}</p>
<input class="but" type="submit" value="登录">
</form>
</div>
</body>
</html>
login.html
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>登陆</title>
</head>
<body>
<div id="login">
<h2>系统登陆</h2>
<form method='post'>
{% csrf_token %}
<p><label>用户: </label>{{form.username}}</p>
<p><label>密码: </label>{{form.password}}</p>
<input class="but" type="submit" value="登录">
</form>
</div>
</body>
</html>