标签:独立 erro 提示信息 val 钩子 char 写入 访问 工具
内容回顾
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作为一个完美主义者的终极框架,当然也会想到用户的这些痛点。它内置了强大的用户认证系统--auth,它默认使用 auth_user 表来存储用户数据。
首先执行数据库迁移的两条命令,然后再数据库中会有这样一个表,author_user,这是django自带的一个用户表。
通过django创建超级用户:
python manage.py createsuperuser
提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username 、password两个关键字参数。
如果认证成功(用户名和密码正确有效),便会返回一个 User 对象。
authenticate()会在该 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})
该函数接受一个HttpRequest对象,无返回值。
当调用该函数时,当前请求的session信息会全
def logout(request): #注销 auth.logout(request) return redirect(‘/login/‘)
这样就清楚了session数据。
现在如果我们直接输入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/‘ # 这里配置成你项目登录页面的路由
用来判断当前请求是否通过了认证。
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自己的表,所以不能像之前用我们自己的表的创建方法去创建用户,这里提供了:
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})
auth 提供的一个创建新的超级用户的方法,需要提供必要参数(username、password)等。
方法和创建普通用户的方法相同
auth 提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。
密码正确返回True,否则返回False。
ok = user.check_password(‘旧密码‘) #user就是当前登陆的user request.user
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表上添加一个字段怎么办?
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表了。
标签:独立 erro 提示信息 val 钩子 char 写入 访问 工具
原文地址:https://www.cnblogs.com/yb635238477/p/9461714.html