Django 之 Form组件
普通方式手写注册功能
def reg(request): errors = {'username':'','password':''} if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') if 'sb' in username: errors['username'] = '用户名不能有sb' if password.isdigit(): errors['password'] = '不能为纯数字' return render(request,'login.html',locals())
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.0/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.0/js/bootstrap.min.js"></script> <style> span{ color: red; } </style> </head> <body> <form action="" method="post"> <p>username<input type="text" name="username"> <span>{{ errors.username }}</span> </p> <p>password<input type="password" name="password"> <span>{{ errors.password }}</span> </p> <input type="submit" value="提交"> </form> </body> </html>
用form组件实现注册功能
django form组件
1.渲染标签
2.校验数据
3.展示信息
渲染标签
第一步先定义一个Form类
第二步实例化form对象
form_obj = MyForm({'name':'jason'})
from app01 import views form_obj = views.MyForm({'name':'asd','password':'a654','email':3215}) form_obj.is_valid() False form_obj.errors {'email': ['Enter a valid email address.']}
- form_obj.is_valid() 可以判断RegForm实例化传值对不对,返回True,False
- form_obj.errors 返回所有校验未通过的字段及错误提示
- form_obj.cleaned_data 返回的是符合校验规则数据,存的是字典
注意:实例化时,如果传值传多了不影响,不会去校验这个多出来的值,会当它不存在,如果少传了值,form_obj.is_valid()就会是false,form_obj.errors报错{'email': ['This field is required.']},这个时候我们可以在字段后面设置required=False,这样就不用传值了
第三步查看数据校验是否合法
form_obj.is_valid() # 只有当所有的字段都校验通过才会返回True
第四步查看校验错误的信息
form_obj.errors # 这个里面放的是所有校验未通过的字段及错误提示
"""
{
'name': ['Ensure this value has at most 6 characters (it has 7).'],
'password': ['Ensure this value has at least 3 characters (it has 2).'],
'email': ['Enter a valid email address.']
}
"""
第五步查看校验通过的数据
form_obj.cleaned_data # 符合校验规则数据都会被放到该对象中
ps:form组件校验数据的规则从上往下依次取值校验
校验通过的放到cleaned_data
校验失败的放到errors
渲染标签
form组件只帮你渲染获取用户输入的标签,不会帮你渲染提交按钮,需要手动添加
第一种渲染方式(可扩展性较差)
{{ form_obj.as_p }}
{{ form_obj.as_ul }}
第二种渲染方式
<form action="">
<p>{{ form_obj.name.label }}{{ form_obj.name }}</p>
<p>{{ form_obj.password.label }}{{ form_obj.password }}</p>
<p>{{ form_obj.email.label }}{{ form_obj.email }}</p>
<input type="submit">
</form>
输入框前面的提示词默认是字段名的首字母大写,我们可以通过添加label=""来修改
第三种渲染标签的方式
<form action="">
{% for foo in form_obj %}
<p>{{ foo.label }}{{ foo }}</p>
{% endfor %}
</form>
前端取消校验
<form action="" method="post" novalidate>
</form>
form综合使用
后端
from django import forms class MyForm(forms.Form): name = forms.CharField(max_length=6,label='用户名',error_messages={ 'max_length':'用户名最长不超过6位', 'required': '用户名不能为空' }) #error_messages={}自定义错误提示,label='用户名',修改输入框前面的默认Name,Password password = forms.CharField(max_length=6,min_length=3,error_messages={ 'max_length':'密码最长不超过6位', 'min_length':'密码至少3位', 'required': '密码不能为空' }) email = forms.EmailField(error_messages={ 'invalid':'邮箱格式不正确', 'required': '邮箱不能为空' }) def reg(request): # 先生成一个空对象 form_obj = MyForm() if request.method == 'POST': print(request.POST) form_obj = MyForm(request.POST) if form_obj.is_valid(): models.User.objects.create(**form_obj.cleaned_data) return render(request, 'reg.html', locals())
error_messages={}自定义错误提示,
label='用户名',修改输入框前面的默认Name,Password
前端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.0/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.0/js/bootstrap.min.js"></script> </head> <body> <h1>第三种渲染方式</h1> <form action="" method="post" novalidate> {% for foo in form_obj %} <p>{{ foo.label }}{{ foo }} <span> {{ foo.errors.0 }}</span> </p> {% endfor %} <input type="submit" value="提交"> </form>
效果展示
钩子函数
局部钩子函数 (单个字段的校验利用局部钩子函数)
class MyForm(forms.Form): name = forms.CharField(max_length=6,label='用户名',error_messages={ 'max_length':'用户名最长不超过6位', 'required': '用户名不能为空' }) password = forms.CharField(max_length=6,min_length=3,error_messages={ 'max_length':'密码最长不超过6位', 'min_length':'密码至少3位', 'required': '密码不能为空' }) confirm_password = forms.CharField(max_length=6, min_length=3, error_messages={ 'max_length': '确认密码最长不超过6位', 'min_length': '确认密码至少3位', 'required': '确认密码不能为空' }) email = forms.EmailField(error_messages={ 'invalid':'邮箱格式不正确', 'required': '邮箱不能为空' }) def clean_name(self): name = self.cleaned_data.get('name') if 'sb' in name: self.add_error('name','说脏话是不好地。。') return name
全局钩子函数 (多个字段的校验利用全局钩子函数)
def clean(self): password = self.cleaned_data.get('password') confirm_password = self.cleaned_data.get('confirm_password') if password != confirm_password: self.add_error('confirm_password','两次密码不一致') return self.cleaned_data
效果展示
设置标签样式
from django import forms from django.forms import widgets password = forms.CharField(max_length=8,min_length=3,error_messages={ 'max_length': '密码最长8位', 'required': '密码不能为空', 'min_length':'密码最少3位' },widget=widgets.PasswordInput(attrs={'class':'c1 form-control'})) #widget=widgets.PasswordInput设置密码密文,(attrs={'class':'c1 form-control'})设置样式 hobby = forms.ChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=3,#设置默认值 widget=forms.widgets.Select() ) hobby1 = forms.MultipleChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=[1, 3], widget=forms.widgets.SelectMultiple() ) keep = forms.ChoiceField( label="是否记住密码", initial="checked", widget=forms.widgets.CheckboxInput() )