实现的功能:
用户提交数据效验数据
错误,页面上显示错误提示
利用循环优化模版展示代码
关联的数据 循环展示在页面上
my_forms.py
rom django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError
from app01.utils.encrypt import md5
定义一个BootStrapModelForm继承自forms.ModelForm来实现展示数据表格样式的统一设置
field.label:显示字段models中的verbose_name
class BootStrapModelForm(forms.ModelForm):
"""只需要让其他的类继承自这个类 便可以共同使用css样式"""
def __init__(self, *args, **kwargs):
"""重写父类的初始化方法"""
super().__init__(*args, **kwargs)
# 循环找到所有的插件,添加class=form-control的样式
# 字段中原有的样式属性,保留属性。没有属性,再增加样式属性
for name, field in self.fields.items():
# 如果有有 默认的样式值
if field.widget.attrs:
field.widget.attrs['class'] = 'form-control'
field.widget.attrs['placeholder'] = field.label
# 否则 没有 设置统一的样式值
else:
field.widget.attrs = {'class': 'form-control', 'placeholder': field.label}
# 重置密码的ModelForm
class AdminResetModelForm(BootStrapModelForm):
# 创建一个确认密码的字段 render_value=True密码输入错误保留密码
confirm_password = forms.CharField(label='确认密码', widget=forms.PasswordInput(render_value=True))
# 钩子方法 用来验证字段数据
def clean_password(self):
# 通过self.cleaned_data可以得到views中经过form.is_valid()验证的数据
pwd = self.cleaned_data.get('password')
# 通过md5对密码进行加密
md5_pwd = md5(pwd)
# 当前的密码是否存在 self.instance.pk 得到 id
if Admin.objects.filter(id=self.instance.pk, password=md5_pwd):
raise ValidationError('密码不能与之前的相同')
# 返回加密后的密码,保存到数据库
return md5_pwd
def clean_confirm_password(self):
confirm = self.cleaned_data.get('confirm_password')
confirm = md5(confirm)
password = self.cleaned_data.get('password')
if confirm != password:
raise ValidationError('密码不一致')
else:
# 需要返回 放到cleaned_data中 如果返回一个 999, 视图中form.cleaned_data为999固定的
# return的值 为保存到数据库中的值
return confirm
# meta类指定模型 和 fields字段
class Meta:
model = Admin
fields = ['password', 'confirm_password']
# fields = '__all__'
# 自定义password
widgets = {
'password': forms.PasswordInput(render_value=True)
}
视图函数
def admin_reset(request, nid):
"""重置密码 编辑密码"""
# 此处需要加first获取第一个对象数据,否则QuereySet传入后面instance报错
row_obj = Admin.objects.filter(id=nid).first()
if request.method == 'GET':
# 没有获取到数据重定向会用户展示中心
if not row_obj:
return redirect('/admin/list/')
else:
# 这里擦混入instance=obj 相当于增加占位符为原来数据库中的默认值
# form = AdminResetModelForm(instance=row_obj) # 不传instance就没有默认值
# 指定form
form = AdminResetModelForm()
# 将页面的标题传给后端
title = '重置密码 - {} '.format(row_obj.username)
# 渲染页面
return render(request, 'change.html', locals())
elif request.method == 'POST':
# 编辑数据需要传入 1.data=request.POST 2.instance=row_obj
# 不传入row_obj会新建数据
form = AdminResetModelForm(data=request.POST, instance=row_obj)
# 验证数据
if form.is_valid():
# 保存到数据库中
form.save()
return redirect('/admins/list/')
# 验证失败重新render页面,此时HTML中得到field.errors.0错误信息
else:
return render(request, 'change.html', locals())
HTML中
{% extends 'layout.html' %}
{% block content %}
{#
对后端传过来的form进行遍历
得到field
field.label:verbose_name/label字段属性
field:得到的为字段值
field.error:如果有错误(如该处不为空),会显示在浏览器上只需要获取第一个错误所以 field.error.0
#}
<!--添加表单-->
<div class="container">
<div style="margin-bottom: 10px">
<a class="panel-heading"> <!--target=_blank在新页面打开-->
<h3 class="panel-title">{{ title }}</h3>
</a>
</div>
<form method="post" novalidate>
{% csrf_token %}
<div class="mb-3">
{% for field in form %}
<div class="form-group">
<label>{{ field.label }}</label>
{{ field }}
<span style="color: red;">{{ field.errors.0 }}</span>
</div>
{% endfor %}
</div>
<button type="submit" class="btn btn-primary">保存</button>
</form>
</div>
{% endblock %}
哈希算法 md5加密算法使用学习
"""
特点
1.定长输出:md5 32位 16进制
2.不可逆:无法方向计算出对应明文
3.雪崩效应:输入密码改变一点,结果完全不同
使用场景
1.密码加密
2.文件完整性检验
使用方案
import hashlib
m = hashlib.md5(salt) salt加不加都可以
m.update(b'123') 传入二进制
value = m.hexdigest() 结果为16进制
value = m.digest 结果为非16进制
"""
import hashlib
from django.conf import settings
def md5(data_string):
"""定长生成32为16进制加密数据"""
# 加盐
salt = settings.SECRET_KEY.encode('utf-8')
# 根据salt生成规则进行加密
obj = hashlib.md5(salt)
obj.update(data_string.encode('utf-8'))
return obj.hexdigest()