DAY86-Django框架(十六) auth组件

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/')

猜你喜欢

转载自www.cnblogs.com/xvchengqi/p/10022309.html
今日推荐