一、auth组件默认auth_user表常用操作
from django.contrib.auth.models import User
# 1、创建普通用户
User.objects.create_user(username='Owen', password='123')
# 2、创建超级用户
User.objects.create_superuser(username='root', password='root', email='root@root.com') # 此方法django内部源码未给email传入默认参数,因此此处需要手动传值才能创建
# 3、获取第一个用户
user = User.objects.first()
# 4、修改密码
user.set_password('000')
user.save() # 修改时一定要记得保存
# 5、校验密码
res = user.check_password('000')
二、auth组件常用功能
# 1、校验用户账号及密码,校验成功返回user对象
from django.contrib.auth import authenticate
user = authenticate(username=usr, password=pwd)
# 2、注册用户到request对象中,注册成功可以request.user访问当前登录用户(会形成session记录)
from django.contrib.auth import login
login(request, user) # 注册authenticate成功(当前登录)的用户
# 3、注销当前注册的user (用户注销)
from django.contrib.auth import logout
logout(request)
# 4、校验用户登录状态
# 视图函数中使用
if request.user.is_authenticated(): pass
# 模板语言中使用
{% if request.user.is_authenticated %}
{% else %}
{% endif %}
# 5、校验登录状态的装饰器
from django.contrib.auth.decorators import login_required
@login_required(login_url='/user_login/')
def user_home(request):
return render(request, 'user.html', locals())
三、扩展auth_user表 -- 替换为app_user表
# app/models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
# 增加自定义字段
info = models.TextField(null=True)
# settings.py配置
AUTH_USER_MODEL = 'app.User'
四、Form完成表单校验 (自定义错误信息)
1. 校验的字段属性名要与校验的表单form的表单元素name值进行匹配
2. 校验字段的参数required,默认为True(也与自定义True),代表数据必须传入该校验值,如果设置为False,校验数据中可以不包含该校验值
3. error_messages自定义校验规则的校验失败的(中)错误信息
from django import forms
class CheckForm(forms.Form):
usr = forms.CharField(min_length=3, max_length=10)
pwd = forms.CharField(
min_length=3,
max_length=10,
error_messages={
"min_length": "最少3", # 某个校验规则对应的 中文提示 错误信息
"max_length": "最多10",
'required': "必填项" # 除了自定义校验规则,还可以明确默认校验规则的 中文提示 错误信息
}
)
def register(request):
check_form = CheckForm(request.POST)
if check_form.is_valid():
print("校验成功")
print(check_form.cleaned_data)
else:
print("校验失败")
print(check_form.cleaned_data) # 部分成功的数据
# from django.forms.utils import ErrorDict
print(check_form.errors) # 部分失败的信息
五、局部钩子:
在系统提供的校验结束后,在对具体的字段进行自定义二次校验
class CheckForm(forms.Form):
usr = forms.CharField(...)
# ...
# 局部钩子
def clean_usr(self):
cleaned_usr = self.cleaned_data.get('usr', None)
# 自定义校验规则
import re
if re.match('^[0-9]', cleaned_usr): # 通过正则匹配不能以数字开头
from django.core.exceptions import ValidationError
raise ValidationError('不能以数字开头') # 抛ValidationError信息就会被添加到self.errors中
return cleaned_usr
六、全局钩子
在系统提供的校验结束后,在对所有的字段进行自定义二次校验
class CheckForm(forms.Form):
# ...
# 全局钩子
def clean(self):
cleaned_pwd = self.cleaned_data.get('pwd', None)
cleaned_re_pwd = self.cleaned_data.get('re_pwd', None)
if cleaned_pwd != cleaned_re_pwd:
from django.core.exceptions import ValidationError
raise ValidationError('两次密码不一致') # 抛ValidationError信息就会被添加到self.errors中
return self.cleaned_data
七、模板渲染
class CheckForm2(forms.Form):
# 校验需求:账号必须不能以数字开头
usr = forms.CharField(min_length=3, max_length=10, label="账号:",
error_messages={
'required': "必填项",
'min_length': "最少3",
'max_length': "最多10"
})
pwd = forms.CharField(min_length=3, max_length=10, label="密码:",
error_messages={
'required': "必填项",
'min_length': "最少3",
'max_length': "最多10"
},
widget=forms.PasswordInput(attrs={
'class': 'pwd',
'placeholder': '请输入密码'
})
)
re_pwd = forms.CharField(min_length=3, max_length=10, label="确认:",
error_messages={
'required': "必填项",
'min_length': "最少3",
'max_length': "最多10"
},
widget=forms.PasswordInput)
email = forms.EmailField(label="邮箱:",
error_messages={
'invalid': "格式不正确",
'required': "必填项"
}
)
# 局部钩子:对usr进行局部钩子的校验,该方法会在usr属性校验通过后,系统调用该方法继续校验
def clean_usr(self):
cleaned_usr = self.cleaned_data.get('usr', None) # type: str
# 通过正则匹配不能以数字开头
import re
if re.match('^[0-9]', cleaned_usr):
from django.core.exceptions import ValidationError
raise ValidationError('不能以数字开头')
return cleaned_usr
# 全局钩子:代表校验类中的所有属性校验通过后,系统调用该方法继续校验
def clean(self):
cleaned_pwd = self.cleaned_data.get('pwd', None)
cleaned_re_pwd = self.cleaned_data.get('re_pwd', None)
if cleaned_pwd != cleaned_re_pwd:
from django.core.exceptions import ValidationError
raise ValidationError('两次密码不一致')
return self.cleaned_data
def register2(request):
if request.method == "GET":
check_form2 = CheckForm2()
if request.method == "POST":
check_form2 = CheckForm2(request.POST)
if check_form2.is_valid():
return HttpResponse('注册成功')
else:
print(check_form2.errors.as_data)
all_error = check_form2.errors.get('__all__')
return render(request, 'register2.html', locals())
<form action="" method="post" novalidate>
{% for ele in check_form2 %}
<p>
<label for="">{{ ele.label }}</label>
{{ ele }}
<span style="color: red;">{{ ele.errors.0 }}</span>
{% if ele == check_form2.re_pwd %}
<span style="color: red;">{{ all_error.0 }}</span>
{% endif %}
</p>
{% endfor %}
<input type="submit" value="注册">
</form>