zoukankan      html  css  js  c++  java
  • 十三:Django框架学习之auth模块

    什么是auth模块?

    auth模块django自带的用户认证模块。

    """
    我们在开发一个网站的时候,无可避免的要设计实现用户登录系统。其中,设计到的需求就包括但不限于用户注册,用户登录、用户认证、注销、修改密码等功能。
    
    显而易见,这种重复造轮子的事情,django框架作为一个完美主义者自然会考虑到。它内置了强大的用户认证系统——auth,默认是使用auth_user表来存储用户的数据。
    """
    

    auth模块的常用方法

    from django.contrib import auth
    
    • authenticate()

    验证用户的用户名以及密码是否正确

    user_obj = auth.authenticate(
        request,
        username='username',
        password='password',
    )
    """
    (1)关于参数,括号内必须同时传入用户名以及密码;
    (2)数据都符合,返回一个用户对象user_obj,数据不符合则返回None。
    """
    
    • login()

    保存用户的登录状态信息

    该函数接受一个HttpRequest对象,以及一个经过认证的User对象。该函数本质上会在后端为该后端生成相关的session数据。

    auth.login(
        request,
        user_obj,
    )
    """
    (1)其类视于request.session[key] = user_obj;
    (2)执行该方法后,会将user_obj对象封装到request.user中:
    print(request.user)   # user_obj对象
    print(request.user.username)  # jason
    print(request.user.password)  # dbj123
    """
    
    • is_authenticated()

    用来判断当前的请求是否经过了认证,返回一个布尔值

    if not request.user.is_authenticated():
        return redirect('%s?next=%s' % (settings.LOGIN_URL,request.path,))
    
    • login_required()

    auth 模块提供的登录认证装饰器

    from django.contrib.auth.decorators import login_required
    
    # 局部配置
    @login_required(login_url='/login/')
    # 全局配置
    在setiings.py中添加一个全局环境变量
    LOGIN_URL = '/login/'
    
    # 局部配置&全局配置
    (1)局部配置的优先级要高于全局配置;
    (2)全局的好处在于无需写重复的代码,但是跳转的页面单一,
    局部的好处是不同的视图函数在用户没有登录的情况下可以跳转到不同的页面。
    
    • create_user()

    auth提供的创建普通用户的方法,需要提供必要参数username,password

    from django.contrib.auth.models import User
    
    user_obj = User.objects.create_user(username='username',password='password',email='email'...)
    
    • create_superuser()

    auth提供的创建超级用户的方法,需要提供必要参数username,password,email

    from django.contrib.auth.models import User
    
    user_obj = User.objects.create_superuser(
        username='username',
        password='password',
        email='email',
    )
    """
    注意:使用代码创建超级用户的时候必须填邮箱,使用命令行创建超级用户的时候可以不填邮箱。
    
    使用命令行创建超级用户
    python manage.py createsuperuser
    """
    
    • check_password()

    检查用户输入的密码是否正确,返回一个布尔值

    is_ok = request.user.check_password(old_password)
    
    • set_password()

    auth提供的一个修改密码的功能,需要传入新密码作为参数

    request.user.set_password(new_password) #仅仅是修改对象的属性
    request.user.save()   # 这一步才是操作数据库
    
    """
    一定要记得加上save操作
    """
    
    • logout()

    auth提供的注销功能,该函数接收一个HttpResponse对象,没有返回值。

    当调用该函数时,当前请求的session信息会全部清除。该用户即使没有登录,使用该函数也不会报错。

    from django.contrib import auth
    
    def logout(request):
        auth.logout(request)
        return redirect('/login/')
    

    User对象属性

    User对象属性:username,password

    is_staff:用户是否有网站的管理权限(是否是管理员)

    is_active:是否允许用户登录,设置为False,可以在不删除用户的情况下禁止用户登录

    如何扩展auth_user表

    • 第一种(一对一关系)
    from django.db import models
    # 第一种:一对一关系,不推荐
    class UserDetail(models.Model):
    	phone = models.BigIntegerField()
        user = models.OneToOneField(to='User')
    
    • 第二种(面向对象的继承)

    前提条件

    (1)在继承AbstractUser类前,没有执行过数据库迁移命令,即auth_user表没有被创建;
    (2)继承的类里面不能覆盖AbstractUser类原有字段名称,只扩展额外的字段即可;
    (3)在配置文件settings.py中,告诉django使用User_Info替换auth_user:
     AUTH_USER_MODEL = 'app01.UserInfo'  # '应用名.表名'
    

    models.py

    from django.db import models
    from django.contrib.auth.models import AbstractUser
    
    class UserInfo(AbstractUser):
        GENDER_CHOICE = (
            ('male', '男'),
            ('female', '女'),
            ('secret', '保密'),
        )
        phone = models.CharField(
            max_length=64,
            verbose_name='phone',
            null=False,
        )
        age = models.IntegerField(
            verbose_name='age',
            default=18,
        )
        gender = models.CharField(
            max_length=16,
            choices=GENDER_CHOICE,
            default='secret',
        )
        
        def __str__(self):
            return self.username
    

    执行两条数据库迁移命令

    python manage.py makemigration
    python manage.py migrate
    

    img

    这样auth模块的功能还是能够使用,参考的表由原来的auth_user变成了user_info
    

    使用扩展后的user_info表

    • 注册功能
    def register(request):
        ...
        is_exists = auth.authenticate(
                request,
                username=username,
                password=password,
            )
        if is_exists:
        	return HttpResponse('注册失败,用户已存在!')
        user_obj = models.UserInfo.objects.create_superuser(
        	...
        )
       return HttpResponse('注册成功!')        
    

    img

    img

    • 登录功能
    def login(request):
        if request.method == 'POST':
            ...
            user_obj = auth.authenticate(
                request,
                username=username,
                password=password,
            )
            ...
            auth.login(request, user_obj) # 设置session
            return HttpResponse('登录成功!')
        return render(request, 'login.html', login_dict)
    

    img

    img

    • home页面
    def home(request):
        print(request.user)   # user_obj对象
        print(request.user.is_authenticated()) # 校验用户是否登录
        return HttpResponse('home')
    

    img

    加装饰器,然后清除掉session

    @login_required(login_url='/login/')
    def home(request):
        print(request.user)
        print(request.user.is_authenticated())
        return HttpResponse('home')
    

    img

    • 修改密码功能
    @login_required(login_url='/login/')
    def set_password(request):
        if request.method == 'POST':
            old_password = request.POST.get('old_password')
            new_password = request.POST.get('new_password')
            confirm_password = request.POST.get('confirm_password')
            # 先判断两次密码是否一致
            if new_password == new_password:
                #  在校验老密码是否正确
                is_right = request.user.check_password(old_password)
                if is_right:
                    # 再修改密码
                    request.user.set_password(new_password)  # 仅仅是修改user_obj对象的属性
                    request.user.save()  # 操作数据库,保存修改
                    return redirect('/login/')
                return HttpResponse('输入的老密码不正确!')
            return HttpResponse('两次输入的密码不一致!')
        return render(request, 'set_password.html')
    
    • 注销功能
    @login_required(login_url='/login/')
    def logout(request):
        auth.logout(request)  # request.session.flush()
        return redirect('/login/')
    
  • 相关阅读:
    合并排序法-Java实现
    桶排序(heap sort)-Java实现
    Shell排序法-Java实现
    快速排序法-Java实现
    选择排序法-Java实现
    树状数组例题-数星星,简单题easy,校门外的树2,清点人数
    [USACO]骑马修栅栏 Riding the Fences
    tarjan 割点
    [USACO07OPEN]便宜的回文Cheapest Palindrome
    [AHOI2009]维护序列
  • 原文地址:https://www.cnblogs.com/wait59/p/13945315.html
Copyright © 2011-2022 走看看