auth模块

auth模块

(1)介绍

  • 其实我们在创建好一个Django项目之后直接执行数据库迁移命令会生成很多表
    • django_session
    • auth_user
  • django在启动之后就可以直接访问admin路由,需要输入用户名和密码,数据参考的就是auth_user表,并且还必须是管理员用户才能进入

(2)创建超级用户(管理员)

python manage.py createsuperuser

image

(3)auth.authenticate 校验数据

  • auth.authenticate 要同时传入用户名和密码 一步就筛选出用户对象

  • 自动查找auth_user表

  • 自动给密码加密再比对

def login(request):
    if request.method =='POST':
        username= request.POST.get('username')
        password = request.POST.get('password')
        user_obj = auth.authenticate(request,username=username,password=password)
        print(user_obj) # heart 这是一个用户对象 不符合就返回None
        print(user_obj.username) # heart
        print(user_obj.password) # pbkdf2_sha256$260000$tMm0S4Mp4Oe9DEiCkqzKn6$2Y+PxIGXlLLfaf1sKJ/jDzEYTJmlFOemH9qHJaoXYKY=
    return render(request, 'login.html')

(4)auth.login() 保存用户状态

  • 只要执行了该方法 就可以在任何地方通过request.user获取到当前登录的用户对象
auth.login(request,user_obj) # 类似于request.session[key] = user_obj
def login(request):
    if request.method =='POST':
        username= request.POST.get('username')
        password = request.POST.get('password')
        user_obj = auth.authenticate(request,username=username,password=password)
        if user_obj:
            auth.login(request,user_obj)
    return render(request, 'login.html')

image

(5)is_authenticated 验证用户是否登录

request.user.is_authenticated()
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        user_obj = auth.authenticate(request, username=username, password=password)
        if user_obj:
            auth.login(request, user_obj)
        return redirect(to='home')
    return render(request, 'login.html')


def home(request):
    print(request.user)  # heart 这是一个用户对象 如果没有登陆 AnonymousUser 匿名用户
    res = request.user
    print(res.username)  # heart 这是字符串
    print(request.user.is_authenticated) # 验证用户是否登陆
    return HttpResponse('ok')

(6)登录验证装饰器

  • 局部配置 用户没有登陆就跳转到login_url后面指定的路由
from django.contrib.auth.decorators import login_required
@login_required(login_url='/login/')
def home(request):
    print(request.user)  # heart 这是一个用户对象 如果没有登陆 AnonymousUser 匿名用户
    res = request.user
    print(res.username)  # heart 这是字符串
    print(request.user.is_authenticated()) # 验证用户是否登陆
    return HttpResponse('ok')
  • 全局配置 在settings文件中添加
LOGIN_URL = '/login/'
@login_required
def home(request):
    print(request.user)  # heart 这是一个用户对象 如果没有登陆 AnonymousUser 匿名用户
    res = request.user
    print(res.username)  # heart 这是字符串
    print(request.user.is_authenticated()) # 验证用户是否登陆
    return HttpResponse('ok')

局部/全局优先级

​ 局部大于全局

各自的优点

​ 全局的好处在于无需书写重复的代码,但是页面的跳转很单一

​ 局部的好处是在于不同的视图函数再用户没有登陆的情况下可以跳转到不同的页面

(7)修改密码

  • 比对输入的密码和原密码是否相符 check_password(旧密码)
  • 设置密码 set_password(新密码)
  • 设置完要保存 save()
@login_required
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 == confirm_password:
            # 校验旧密码是否相同
            is_right = request.user.check_password(old_password)  # 内部对加密密码进行比对
            # 返回的结果为布尔值
            if is_right:
                # 修改密码
                request.user.set_password(confirm_password) # 仅仅在修改对象的属性
                # 修改完密码后进行保存数据
                request.user.save()
        return redirect('/login/')
    return render(request, 'set_password.html', locals())
<form action="" method="post">
    {% csrf_token %}
    <p>username:<input type="text" name="username" disabled value="{{ request.user.username }}"></p>
    <p>old_password:<input type="text" name="old_password"></p>
    <p>new_password:<input type="text" name="new_password"></p>
    <p>confirm_password:<input type="text" name="confirm_password"></p>
    <input type="submit" class="btn btn-success">
</form>

(8)注销

@login_required
def login_out(request):
    auth.logout(request)  # 清空当前登录用户的数据 ----- request.session.flush()
    return redirect('/login/')

(9)注册

from django.contrib.auth.models import User
def register(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 操作auth_user表写入数据
        # User.objects.create(username=username, password=confirm_password)  # 会写入数据,但是保存的密码是明文的,没有加密
        # 创建普通用户
        User.objects.create_user(username=username, password=password)
        # 创建超级用户 - 了解 --- 使用代码创建超级用户,邮箱是必填的,而用命令行创建可以忽略邮箱
        # User.objects.create_superuser(username=username, password=password,email=123@qq.com)
    return render(request, 'register.html')

(10)auth模块表扩展

(1)方式一

from django.db import models
from django.contrib.auth.models import User

# 扩展 auth_user 表
# 第一种方式 : 一对一关系(不推荐)
class UserDetail(models.Model):
    phone = models.CharField(max_length=11)
    user = models.OneToOneField(to='User', on_delete=models.CASCADE)

(2)方式二

from django.db import models
from django.contrib.auth.models import User, AbstractUser

# 第二种方式 : 面向对象的继承
class UserInfo(AbstractUser):
    '''
    如果继承了AbstractUser
    那么在执行数据库迁移命令的时候,auth_user表就不会被创建
    而 UserInfo 会在 auth_user表 的基础上添加自定义扩展的字段

    优点:
        直接通过自己定义的表快速完成操作及扩展

    前提
        (1)在执行之前没有执行过数据库迁移命令
            auth_user 表没有被创建
            如果当前库已经被创建,则需要更换新的库
        (2)继承的类里面不要覆盖 AbstractUser 里面的字段名
            表里面有的字段不要动,只扩展额外的字段即可
        (3)需要再配置文件中声明Django要使用 UserInfo 替代 auth_user
            AUTH_USER_MODEL = 'app01.UserInfo'  ---'应用名.表名'
    '''
    phone = models.CharField(max_length=32)

需要再配置文件中声明 Django 要使用 UserInfo 替代 auth_user

 AUTH_USER_MODEL = 'app01.UserInfo'  ---'应用名.表名'

如果自己写表代替了 auth_user
auth模块功能正常使用,参考的表也由 auth_user 变成了 UserInfo

posted @ 2024-03-29 09:55  ssrheart  阅读(1)  评论(0编辑  收藏  举报