zoukankan      html  css  js  c++  java
  • 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/')
    
  • 相关阅读:
    1JavaScript的历史
    扯扯 require .js
    查看js 执行效率工具
    php 输入输出流
    词法分析096
    Python基础综合练习
    096
    大数据概述
    熟悉常用的Linux操作
    实验一、词法分析实验
  • 原文地址:https://www.cnblogs.com/xvchengqi/p/10022309.html
Copyright © 2011-2022 走看看