django框架之auth模块

内容回顾
    1. form表单组件
        1. 常用字段
            1. CharField()
            2. ChoiceField()
        2. 参数或配置
            1. label="label标签显示的文本内容"
            2. initial="默认值"
            3. widget=forms.widgets.TextInput()   --> <input typle='text'/>
               widget=forms.widgets.PasswordInput(
                    attrs={"class": "c1", "s12": "hao"}
               )
            4. required=False                     --> is_valid()校验的时候该字段没有值也不报错
            5. error_messages={"required": "xx字段不能为空", "max_length": "xx字段最多不能超过位数"}
            6. max_length
            7. min_length
            
            8. validators=[验证器1,验证器2, ...]
        3. 验证器
            1. 内置正则验证
                from django.core.validators import RegexValidator
                validators=[RegexValidator(r'^1[3-9]\d{9}$', "手机号码格式不正确!"), ]
            2. 自定义方法实现
                from django.core.exceptions import ValidationError
                # 自定义校验的方法
                def name_check(value):
                    if '西游记' in value:
                        raise ValidationError("不符合社会主义核心价值观!")
                    else:
                        return value
                        
                validators=[name_check, ],
        4. 钩子函数
            0. self.cleaned_data     --> 用来存放经过验证数据的大字典
               self.add_error("字段名", "错误提示信息")
               
            1. 局部钩子(Hook)
                通过自定义一个clean_字段名的方法实现字段的校验
            2. 全局钩子
                此时 每个字段独立的校验都走完了,cleaned_data中已经存放着所有字段的数据
                def clean(self):
                    print("我可是看过源码的人,我知道你肯定会执行这个方法!")
                    # 重写父类的clean方法
                    # 该clean方法, 在每个字段都校验通过之后才调用执行
                    pwd = self.cleaned_data.get("pwd")
                    re_pwd = self.cleaned_data.get("re_pwd")

                    if re_pwd and re_pwd == pwd:
                        # 确认密码和密码相同, 正常
                        return self.cleaned_data
                    else:
                        # 确认密码和密码不同
                        self.add_error('re_pwd', "两次密码不一致")  # ?
                        raise ValidationError("两次密码不一致")

今日内容:

Django自带的用户认证:

我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,这还真是个麻烦的事情呢。

Django作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。

auth模块:

首先执行数据库迁移的两条命令,然后再数据库中会有这样一个表,author_user,这是django自带的一个用户表。

通过django创建超级用户:

python manage.py createsuperuser

authenticate()   :

提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。

如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。

authenticate()会在该 User 对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

用法:

login(HttpRequest, user)

该函数接受一个HttpRequest对象,以及一个经过认证的User对象。

该函数实现一个用户登录的功能。它本质上会在后端为该用户生成相关session数据。

我们写一个登陆认证的例子:

我们在认证的时候,因为author_user是django自带的表,所以我们没办法用  models.类名  去数据库里面查询username和password,这时候就要:

from django.contrib import auth

def login(request):
err_msg = ''
if request.method == 'POST':
username = request.POST.get('username')
password = request.POST.get('pwd')
# username 和password 都匹配成功就返回一个user对象.
user = auth.authenticate(username=username, password=password)
if user:
#用户名 密码正确
# 1 让当前用户登录,给session和cookie写入数据
auth.login(request,user)
return redirect(request,‘index.html’)
else:
#用户名或密码错误
err_msg = '用户名或密码错误'
return render(request,'login.html',{'err_msg':err_msg})


logout(request) :

该函数接受一个HttpRequest对象,无返回值。

当调用该函数时,当前请求的session信息会全

def logout(request):
    #注销
    auth.logout(request)
    return redirect('/login/')

这样就清楚了session数据。

login_requierd()

现在如果我们直接输入index页面的网址,也是可以直接访问的。这显然不是我们想要的,我们需要先登陆然后再进入index页面。

auth 给我们提供的一个装饰器工具,用来快捷的给某个视图添加登录校验。

from django.contrib.auth.decorators import login_required

@login_required
def index(request):
    return render(request,'index.html')

若用户没有登录,则会跳转到django默认的 登录URL '/accounts/login/ ' 并传递当前访问url的绝对路径 (登陆成功后,会重定向到该路径)。

如果需要自定义登录的URL,则需要在settings.py文件中通过LOGIN_URL进行修改。

LOGIN_URL = '/login/'  # 这里配置成你项目登录页面的路由

is_authenticated():

用来判断当前请求是否通过了认证。

def index(request):
    #用来判断当前请求是否通过了认证。
    print(request.user,request.user.is_authenticated())
    return render(request,'index.html')

现在我们写一个注册,利用之前学过的form表单,让用户去填写,然后拿用户的信息在试图的函数中认证登陆。

创建一个forms文件夹:

from django import forms


class RegForm(forms.Form):
    username = forms.CharField(
        label='用户名',
    )
    password = forms.CharField(
        label='密码',
        widget = forms.widgets.PasswordInput()
    )
    re_password = forms.CharField(
        label='确认密码',
        widget = forms.widgets.PasswordInput()
    )

views.py代码:

from app01 import forms


def register(request):
    form_obj = forms.RegForm()
    if request.method == 'POST':
        from_obj = forms.RegForm(request.POST)
      。。。
    return render(request,'register.html',{'form_obj':form_obj})

html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
<form action="/register/">
    {% csrf_token %}
{#    {{ form_obj.as_p }}#}
    <div>
        <label for="{{ form_obj.username.id_for_label }}">{{ form_obj.username.label }}</label>
        {{ form_obj.username }}
    </div>
    <div>
        <label for="{{ form_obj.password.id_for_label }}">{{ form_obj.password.label }}</label>
        {{ form_obj.password }}
    </div>
    <div>
        <label for="{{ form_obj.re_password.id_for_label }}">{{ form_obj.re_password.label }}</label>
        {{ form_obj.re_password }}
    </div>
    <input type="button" value="注册">
</form>
</body>
</html>

由于这是django自己的表,所以不能像之前用我们自己的表的创建方法去创建用户,这里提供了:

create_user():

auth 提供的一个创建新用户的方法,需要提供必要参数(username、password)等。

def register(request):
    form_obj = RegForm()
    if request.method == 'POST':
        form_obj = RegForm(request.POST)
        if form_obj.is_valid():
            print(form_obj.cleaned_data)#打印form表单中经过验证的数据 cleaned_data中多了re_password字段。
            # 吧re_pqssword字段从cleaned_data移除
            form_obj.cleaned_data.pop('re_password')
            User.objects.create_user(**form_obj.cleaned_data)
            return  HttpResponse('ok')
    return render(request,'register.html',{'form_obj':form_obj})

create_superuser():

auth 提供的一个创建新的超级用户的方法,需要提供必要参数(username、password)等。

方法和创建普通用户的方法相同

check_password(password):

auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。

密码正确返回True,否则返回False。

 
ok = user.check_password('旧密码')     #user就是当前登陆的user   request.user
 

set_password(password):

auth 提供的一个修改密码的方法,接收 要设置的新密码 作为参数。

注意:设置完一定要调用用户对象的save方法!!!

 
user.set_password(‘新密码’)
user.save()
 

一个修改密码功能的简单示例:

views.py代码:

def setpassword(request):
    err_msg = ''
    if request.method == 'POST':
        # print(request.user)
        # print(request.user.password)
        # print(request.user.username)
        user = request.user
        old_password = request.POST.get('old_password')
        new_password = request.POST.get('new_password')
        print(old_password, new_password)
        if user.check_password(old_password):
            user.set_password(new_password)
            user.save()
            return redirect('/login/')
        else:
            err_msg = '原密码输入有误'
    return render(request,'setpassword.html',{'err_msg': err_msg})

html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改密码</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    <div>
        <label for="old_password">原密码:</label>
        <input type="text" name="old_password">
    </div>
    <div>
        <label for="new_password">新密码:</label>
        <input type="password" name="new_password">
    </div>
    <input type="submit" value="提交">
    <span>{{ err_msg }}</span>
</form>
</body>
</html>

现在我们想要在auth_user表上添加一个字段怎么办?

扩展默认的auth_user表:

from django.contrib.auth.models import AbstractUser
class UserInfo(AbstractUser):
    """
    用户信息表
    """
    phone = models.CharField(max_length=11, null=True, unique=True)

注意:

按上面的方式扩展了内置的auth_user表之后,一定要在settings.py中告诉Django,我现在使用我新定义的UserInfo表来做用户认证。写法如下:

# 引用Django自带的User表,继承使用时需要设置
AUTH_USER_MODEL = "app名.UserInfo"

再次注意:

一旦我们指定了新的认证系统所使用的表,我们就需要重新在数据库中创建该表,而不能继续使用原来默认的auth_user表了。

猜你喜欢

转载自www.cnblogs.com/yb635238477/p/9461714.html
今日推荐