# auth
# --settings.py
...
LOGIN_URL = '/login/' # 这里配置成你项目登录页面的路由
AUTH_USER_MODEL = "app01.UserInfo" # 使用的数据库,这个不是路径
# --url.py
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login/', views.login),
url(r'^index/', views.index),
url(r'^logout/', views.logout),
url(r'^reg/', views.reg),
]
# --models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
phone = models.CharField(max_length=11, )
#login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
#以上代码告诉IE浏览器,IE8/9及以后的版本都会以最高版本IE来渲染页面
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<form action="" method="post" autocomplete="off" novalidate>
{% csrf_token %}
<p>
用户名:
<input type="text" name="username">
</p>
<p>
密码:
<input type="password" name="pwd">
</p>
<p>
<button>登录</button>
</p>
<p>
<span>{{ error_msg }}</span>
</p>
</form>
</body>
</html>
#reg.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="x-ua-compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Title</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
{{ form_obj.as_p }} # 使用了form组件
<button>注册</button>
</form>
</body>
</html>
# form.py
# 创建form组件的inut标签
from django import forms
class RegForm(forms.Form):
username = forms.CharField(
label='用户名'
)
password = forms.CharField(
label='密码',
widget=forms.widgets.PasswordInput()
)
re_password = forms.CharField(
label='确认密码',
widget=forms.widgets.PasswordInput()
)
# --views.py
from django.shortcuts import render, HttpResponse, redirect
from django.contrib import auth
from django.contrib.auth.decorators import login_required
from app01.forms import RegForm
from django.contrib.auth.models import User,AbstractUser
def login(request):
error_msg = ''
if request.method == 'POST':
username = request.POST.get('username') # 获取form表单的username
pwd = request.POST.get('pwd')
# 对提交的数据进行认证
obj = auth.authenticate(request, username=username, password=pwd) # 第一个username是关键字,第二个username是变量
#authenticate提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。
#如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。
#authenticate会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。
if obj:
# 登录成功
auth.login(request, obj) # login实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。
return redirect('/index')
else:
error_msg = '用户名或密码错误'
# 返回一个页面让登录
return render(request, 'login.html', {'error_msg': error_msg})
@login_required #login_requierd(), auth 给我们提供的一个装饰器工具,用来快捷的给某个视图添加登录校验。
def index(request):
print(request.user.is_authenticated())
#is_authenticated用来判断当前请求是否通过了认证。
return render(request, 'index.html')
def logout(request):
#该函数接受一个HttpRequest对象,无返回值。
#当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。
auth.logout(request)
return redirect('/login/')
#若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' 并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。
#如果需要自定义登录的URL,则需要在settings.py文件中通过LOGIN_URL进行修改。
#LOGIN_URL = '/login/' # 这里配置成你项目登录页面的路由
def reg(request):
form_obj = RegForm()
if request.method == 'POST':
form_obj = RegForm(request.POST)
if form_obj.is_valid():
form_obj.cleaned_data.pop('re_password') # 获取校验过的username password,这里pop删除了re_password
# 创建普通用户
User.objects.create_user(**form_obj.cleaned_data) # form_obj.cleaned_data是字典这样的{'username': 'alexdsb', 'password': 'alex123'} **form_obj.cleaned_data将字典打散为关键字参数
# create_user用法 :user = User.objects.create_user(username='用户名',password='密码',email='邮箱',...)
# 注意:这里的User是auth表的User,如果使用了扩展表即再model.py中重写了User类并改成名字UserInfo,这时需要引用我们自己写的这个数据库,使用下面代码
# from app01.models import UserInfo
# UserInfo.objects.create_user(**form_obj.cleaned_data)
#创建超级用户,这里需要写email
# User.objects.create_superuser(**form_obj.cleaned_data,email='')
# return redirect('/login/')
#认证用户,login写入session,相当于注册后自动登录了
obj = auth.authenticate(request, **form_obj.cleaned_data)
auth.login(request, obj)
return redirect('/index/')
return render(request, 'reg.html', {'form_obj': form_obj})
1. auth认证
from django.contrib import auth
1. 注册超级用户
python manage.py createsuperuser
2. 认证用户
user = authenticate(request, username=username, password=pwd)
3. 保存登录状态
写入到session中
login(request,user)
4. 注销
删除用户的session
logout(request)
5. 登录状态
request.user.is_authenticated()
6. login_required
登录之后才能访问视图
7. create_user()
8. create_superuser()
9. check_password(password)
10. set_password(password)
11. 扩展表写在models.py中,添加其他字段
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
"""
用户信息表
"""
nid = models.AutoField(primary_key=True)
phone = models.CharField(max_length=11, null=True, unique=True)
# 引用Django自带的User表,继承使用时需要设置,在settings中添加
AUTH_USER_MODEL = "app名.UserInfo"
check_password(password)
#auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。密码正确返回True,否则返回False
用法:(常用在修改密码时再次确认密码)
from django.contrib.auth.models import User
user = User.objects.create_superuser(username='用户名',password='密码',email='邮箱',...)
set_password(password)
auth 提供的一个修改密码的方法,接收 要设置的新密码 作为参数。
注意:设置完一定要调用用户对象的save方法!!!
用法:
user.set_password(password='')
user.save()
一个修改密码功能的简单示例
@login_required
def set_password(request):
user = request.user
err_msg = ''
if request.method == 'POST':
old_password = request.POST.get('old_password', '')
new_password = request.POST.get('new_password', '')
repeat_password = request.POST.get('repeat_password', '')
# 检查旧密码是否正确
if user.check_password(old_password):
if not new_password:
err_msg = '新密码不能为空'
elif new_password != repeat_password:
err_msg = '两次密码不一致'
else:
user.set_password(new_password)
user.save()
return redirect("/login/")
else:
err_msg = '原密码输入错误'
content = {
'err_msg': err_msg,
}
return render(request, 'set_password.html', content)
User对象的属性
User对象属性:username, password
is_staff : 用户是否拥有网站的管理权限.
is_active : 是否允许用户登录, 设置为 False,可以在不删除用户的前提下禁止用户登录