auth模块
1.定义
我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。
Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据
2.基本使用
-
create_user()
功能:
auth 提供的一个创建新用户的方法,需要提供必要参数(username、password)等
语法:
from django.contrib.auth.models import User
user = User.objects.create_user(username=name,password=pwd)
-
create_superuser()
功能:
auth 提供的一个创建新的超级用户的方法,需要提供必要参数(username、password)等
语法:
from django.contrib.auth.models import User
user = User.objects.create_superuser(username=name,password=pwd)
-
authenticate()
功能:
提供了用户认证功能,一般使用用户名和密码验证,其本质就是拿着参数和数据库比对,都正确便返回User对象,否则返回一个None
语法:
from django.contrib.auth import authenticate
user = authenticate(username=name,password=pwd)
print(user)#打印的是用户名
-
login(HttpRequest,user)
功能:
该函数接受一个HttpRequest对象,以及一个经过认证的User对象。该函数实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。一定要是认证通过的才可以登录。
语法:
from django.contrib.auth import authenticate,login
user = authenticate(username=name,password=pwd)
login(request,user)
-
logout(request)
功能:
该函数接受一个HttpRequest对象,无返回值。当调用该函数时,数据库和cookie里的当前的session都会全部清除。该用户即使没有登录,使用该函数也不会报错。
语法:
from django.contrib.auth import logout
logout(request)
-
is_authenticated()
功能:
用来判断当前请求是否通过了认证并且登陆。
语法:
from django.contrib.auth import logout
user = authenticate(username=name,password=pwd)
login(request,user)
print(request.user.is_authenticated())
-
login_requierd()
功能:
auth 给我们提供的一个装饰器工具。如果是没有登陆的话会跳转
语法:
from django.contrib.auth.decorators import login_required
@login_required(redirect_field_name=REDIRECT_FIELD_NAME, login_url=None)
#redirect_field_name:是url中?后的字符串,默认是REDIRECT_FIELD_NAME,也就是next
#login_url:跳转的路径,默认是/accounts/login/,也可以指定
#如果想要全局设置跳转路径,在setting文件里写LOGIN_URL='指定路径'
-
check_password(password)
功能:
auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。
语法:
print(request.user.check_password(pwd))#返回True/False
-
set_password(password)
功能:
auth 提供的一个修改密码的方法,接收 要设置的新密码 作为参数。对当前用户的密码修改。修改完一定要调用save()方法保存
语法:
request.user.set_password('123')
request.user.save()
-
is_staff
功能:
用来判断当前用户是否拥有网站的管理权限。可以设置,但是也要调用save()来保存
语法:
print(request.user.is_staff)
-
**is_active **
功能:
是否允许用户登录, 设置为 False,可以在不删除用户的前提下禁止用户登录。可以设置,但是也要调用save()来保存
语法:
print(request.user.is_active)
3.扩展的User表
由于当前使用的User表是Django为我们已经创建好的,字段都写死了,一旦我们有其他字段的需求,就无法完成。所以为了用户表的灵活性,有两种方法解决。
方式一
新建一张表,存放用户的额外信息,通过一对一的方式,链接到User表
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class UserInfo(models.Model):
phone=models.CharField(max_length=32)
user = models.OneToOneField(to=User)#不能加引号,不然只会在本文件找User
方式二
auth模块的User就是继承AbstractUser,那么我们可以新建一个表模型继承AbstractUser,这样的话之前用到User这个表模型的地方,都要换成UserInfo
from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
phone = models.CharField(max_length=32)
sex = models.BooleanField()
#setting.py
AUTH_USER_MODEL='app01.UserInfo'#不然数据库迁移会失败
4.案例
简单登录,注册,注销
模板组件
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block title %}
Titl
{% endblock %}
</title>
{% load static %}
<link rel="stylesheet" href="{% get_static_prefix %}bootstrap-3.3.7-dist/css/bootstrap.css">
<script src="{% static 'jquery-3.3.1.js' %}"></script>
<style>
{% block css %}
{% endblock %}
</style>
</head>
<body>
{% csrf_token %}
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="#">社团活动管理</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
{% block head-r %}
{% endblock %}
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
{% block middle %}
{% endblock %}
</body>
<script>
{% block js %}
{% endblock %}
</script>
</html>
子组件:head-right.html
<li><a href="{% url 'login' '.html' %}">登录</a></li>
<li><a href="{% url 'register' '.html' %}">注册</a></li>
head_right_login.html
<li><a href="#">{{ name }}</a></li>
<li><a href="/logoff/">注销</a></li>
注册
基于form组件,auth组件和ajax的注册
from app01.models import UserInfo
from django import forms
from django.forms import widgets
class User_from(forms.Form):
name = forms.CharField(label='用户名', max_length=10, min_length=3,
widget=widgets.TextInput({'class': 'form-control'}),
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '不能为空'}, )
pwd = forms.CharField(label='密码', max_length=10, min_length=3,
widget=widgets.PasswordInput({'class': 'form-control'}),
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '不能为空'})
re_pwd = forms.CharField(label='确认密码', max_length=10, min_length=3,
widget=widgets.PasswordInput({'class': 'form-control'}),
error_messages={'max_length': '最长是8', 'min_length': '最短是3', 'required': '不能为空'})
def clean(self):
pwd = self.cleaned_data.get('pwd')
re_pwd = self.cleaned_data.get('re_pwd')
if pwd != re_pwd:
raise ValidationError('两次密码不一致')
return self.cleaned_data
def register(request, html):
dic = {'msg': None, 'errors': None, 'all': None}
if request.method == 'GET':
form = User_from()
return render(request, 'register.html', locals())
if request.method == 'POST':
form = User_from(request.POST)
if form.is_valid():
UserInfo.objects.create_user(username=request.POST.get('name'), password=request.POST.get('pwd'))
dic['msg'] = '注册成功'
else:
all = form.errors.get('__all__')
dic['msg'] = '注册失败'
dic['errors'] = form.errors
dic['all'] = all
print(dic)
return JsonResponse(dic)
import json
def blur(request):
msg=''
if request.method == 'POST':
name = request.POST.get('name')
res = UserInfo.objects.filter(username=name).first()
if res:
msg='该用户已存在'
return HttpResponse(json.dumps(msg))
模板层
{% extends 'base.html' %}
{% block title %}
注册
{% endblock %}
{% block css %}
h1{
margin:0 auto;
text-align:center;
}
{% endblock %}
{% block head-r %}
{% include 'head_right.html' %}
{% endblock %}
{% block middle %}
<h1 class="h1">注册</h1>
<div class="col-md-4 col-md-offset-4 ">
<form>
{% for foo in form %}
<div class="form-group">
<label>{{ foo.label }}</label>
{{ foo }}
</div>
{% endfor %}
</form>
<button id="btn">注册</button>
</div>
{% endblock %}
{% block js %}
$('#btn').click(function () {
var da = {
'name': $('#id_name').val(),
'pwd': $('#id_pwd').val(),
're_pwd': $('#id_re_pwd').val(),
'email': $('#id_email').val(),
'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val(),
}
$.ajax({
url: '{% url 'register' '.html' %}',
data: da,
type: 'post',
success: function (data) {
let ids = [];
$('input').each(function () {
id = $(this).attr('id');
ids.push(id)
});
{#页面显示错误信息#}
for (let i in data.errors) {
let id_name = 'id_' + i;
for (let j = 0; j < ids.length; j++) {
if (id_name == ids[j]){
$('#' + ids[j]).prev('span').remove()
let aa='<spanstyle="height:20px;color:red;float:right">' + data.errors[i] + '</span>';
$('#' + ids[j]).before(aa)
}
}
}
{#页面显示全局错误信息#}
if (data.all) {
$('#btn + span').text('')
$('#btn').after('<span style="color:red;float:right">' + data.all + '</span>')
}
{#页面显示注册是否成功#}
$('h1').html('<span style="color:red">' + data.msg + '</span>');
setTimeout(function () {
location.reload()
},3000)
}
})
});
$('#id_name').blur(function () {
var bb = {'name':$('#id_name').val(),'csrfmiddlewaretoken':$('[name="csrfmiddlewaretoken"]').val()}
$.ajax({
url: '/blur/',
data: bb,
type: 'post',
dataType:'json',
success: function (data) {
let bb = $('<span style="height:20px;color:red;float:right" id="abc">' + data + '</span>')
$('#id_name').before(bb)
}
})
});
$('#id_name').focus(function () {
$('#id_name').prev('span').remove()
{#$('#abc').remove()#}
})
{% endblock %}
登录
from django.shortcuts import render, HttpResponse, redirect
from django.http import JsonResponse
from django.contrib import auth
def login(request, html):
if request.method == 'POST':
name = request.POST.get('name')
pwd = request.POST.get('pwd')
user = auth.authenticate(username=name, password=pwd)
print(user)
if user is not None:
auth.login(request, user)
print(123)
return redirect("/index/")
return render(request, 'login.html')
login.html
{% extends 'base.html'%}
{% block title %}
登录
{% endblock %}
{% block css %}
h1{
margin:0 auto;
text-align:center;
}
{% endblock %}
{% block head-r %}
{% include 'head_right.html' %}
{% endblock %}
{% block middle %}
<h1 class="h1">登录</h1>
<form method="post" class="col-md-4 col-md-offset-4 ">
<div class="form-group">
{% csrf_token %}
<label >用户名</label>
<input type="text" class="form-control" name="name">
</div>
<div class="form-group">
<label for="exampleInputPassword1">密码</label>
<input type="password" class="form-control" id="exampleInputPassword1" name="pwd">
</div>
<input type="submit" value="登录">
</form>
{% endblock %}
首页
from django.shortcuts import render, HttpResponse, redirect
def index(request):
#判断是否登陆
if not request.user.is_authenticated():
flag = 0
else:
name = request.user.username
flag = 1
return render(request, 'index.html', locals())
index.html
{% extends 'base.html' %}
{% block title %}
首页
{% endblock %}
{% block css %}
h1{
margin:0 auto;
text-align:center;
}
{% endblock %}
{% block head-r %}
{% if flag%}
{% include 'head_right_login.html' %}
{% else %}
{% include 'head_right.html' %}
{% endif %}
{% endblock %}
{% block middle %}
<h1 class="h1">首页</h1>
{% endblock %}
注销
def logoff(request):
auth.logout(request)
return redirect('/index/')