一、form是组件
后端代码
from django.shortcuts import render, redirect, HttpResponsedef ab_form(request):back_dict = {'username': '', 'password': ''}if request.method == 'POST':username = request.POST.get('username')password = request.POST.get('password')if '金瓶梅' in username:back_dict['username'] = '不符合规范'if len(password) < 3 and len(password) > 20:back_dict['password'] = '密码的长度只能介于3位到20位的区间'return render(request, 'ab_form.html', locals())from django import formsclass MyForm(forms.Form):username = forms.CharField(min_length=3, max_length=8, label='用户名', error_messages={ 'min_length': '用户名最少3位', 'max_length': '用户名最大8位', 'required': '用户名不能为空', })password = forms.CharField(min_length=3, max_length=8, label='密码', error_messages={ 'min_length': '密码最少3位', 'max_length': '密码最大8位', 'required': '密码不能为空', })confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码', error_messages={ 'min_length': '确认密码最少3位', 'max_length': '确认密码最大8位', 'required': '确认密码不能为空', })email = forms.EmailField(label='邮箱', error_messages={ 'invalid': '邮箱格式不正确', 'required': '密码不能为空', })'''form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '123'})# 校验数据是否合法form_obj.is_valid()Falseform_obj = views.MyForm({'username': 'json', 'password': 123, 'email': 'xx@123.com'})form_obj.is_valid() True # 校验合法的数据有哪些form_obj.cleaned_data{'username': 'json', 'password': '123', 'email': 'xx@123.com'}form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '123'})form_obj.is_valid()Falseform_obj.cleaned_data{'username': 'json', 'password': '123'}# 把不合法的数据找出来form_obj.errors{'email': ['输入一个有效的 Email 地址。']}form_obj = views.MyForm({'username': 'json', 'password': 123})form_obj.is_valid()Falseform_obj.errors{'email': ['这个字段是必填项。']}'''def clean_username(self):username = self.cleaned_data.get('username')if '666' in username:self.add_error('username', '只含有666不行')return usernamedef clean_password(self):password = self.cleaned_data.get('password')confirm_password = self.cleaned_data.get('confirm_password')if not confirm_password == password:self.add_error('confirm_password', '两次密码不一致')return self.cleaned_data'''钩子函数(HOOK):在特定的节点自动触发完成响应的操作在forms组件中有两类钩子1.局部钩子:当你需要给单个字段增加校验规则的时候可以使用2.全局钩子:当你需要给多个字段增加校验规则的时候可以使用案例:1.校验用户名中不能含有666 只是校验username字段,局部钩子2.校验密码和确认密码是否一致 password和confirm两个字段全局钩子'''def index(request):form_obj = MyForm()if request.method == 'POST':'''1.获取数据繁琐2.校验数据需要构造成字典的格式传入才行PS:但是 request.POST 可以看成是一个字典'''form_obj = MyForm(request.POST)if form_obj.is_valid():return HttpResponse('OK')return render(request, 'index.html', locals())
2.前端值index
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title>{% load static %}<script src="{% static 'js/jquery.min.js' %}"></script><link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet"><script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script><script src="{% static 'layer/layer.js' %}"></script></head><body><form action="" method="post" novalidate><p>第一种页面渲染方式: 代码书写少,封装程度太高了,不便于后续的扩展,一般只在本地测试使用</p>{#{{ form_obj.as_p }}#}<p>第二种页面渲染方式:可扩展性很强,但是需要书写的代码太多,一般情况下不用</p>{#{{ form_obj.as_ul }}#}{#<p>{{ form_obj.username.label }}:{{ form_obj.username }}</p>#}{#<p>{{ form_obj.password.label }}:{{ form_obj.password }}</p>#}{#<p>{{ form_obj.email.label }}:{{ form_obj.email }}</p>#}<p>第三种页面渲染方式(推荐使用):代码书写简单,并且扩展性高</p>{#{{ form_obj.as_table }}#}{% for form in form_obj %}<p>{{ form.label }}:{{ form}}<span style="color: red">{{ form.errors.0 }}</span></p>{% endfor %}<input type="submit" class="btn btn-info"></form></body></html>
3.前端之ab_form
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Title</title>{% load static %}<script src="{% static 'js/jquery.min.js' %}"></script><link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet"><script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script><script src="{% static 'layer/layer.js' %}"></script></head><body><form action="" method="post"><div class="container"><div class="row"><div class="col-md-8 col-md-offset-2"><p>username :<input type="text" name="username"><span style="color: darkred">{{ back_dict.username }}</span></p><p>password:<input type="password" name="password"><span style="color: darkred">{{ back_dict.password }}</span></p><input type="submit" class="btn btn-info"></div></div></div></form></body></html>
4.form组件的参数以及单选多选形式
class MyForm(forms.Form):username = forms.CharField(min_length=3, max_length=8, label='用户名', initial='lin', required=False, error_messages={ 'min_length': '用户名最少3位', 'max_length': '用户名最大8位', 'required': '用户名不能为空', }, widget=forms.widgets.TextInput(attrs={'class': 'form-control', 'username': 'lin'}) )password = forms.CharField(min_length=3, max_length=8, label='密码', error_messages={ 'min_length': '密码最少3位', 'max_length': '密码最大8位', 'required': '密码不能为空', }, widget=forms.widgets.PasswordInput() )confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码', error_messages={ 'min_length': '确认密码最少3位', 'max_length': '确认密码最大8位', 'required': '确认密码不能为空', }, widget=forms.widgets.PasswordInput() )email = forms.EmailField(label='邮箱', error_messages={ 'invalid': '邮箱格式不正确', 'required': '密码不能为空', }, widget=forms.widgets.EmailInput() )phone = forms.CharField(validators=[RegexValidator(r'^[0-9]+$', '请输入数字'),RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],)gender = forms.ChoiceField(choices=((1, '男'), (2, '女'), (3, '保密')),label='性别',initial=3,widget=forms.widgets.RadioSelect())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())hobby2 = forms.MultipleChoiceField(choices=((1, '篮球'), (2, '足球'), (3, '双色球')),label='爱好',initial=[1, 3],widget=forms.widgets.CheckboxSelectMultiple())'''forms组件其他参数及补充知识点:label 字段名error_messages自定义报错信息invalid邮箱格式提示信息initial设置默认值required 控制字段是否必填字段没有样式:针对不同类型的input如何修改?通过 widget如:widget=forms.widgets.TextInput()widget=forms.widgets.TextInput(attrs={'class': 'form-control', 'username': 'lin'})注意:需要什么样式,自行添加, 若是多个属性值,直接空格隔开即可widget=forms.widgets.PasswordInput()widget=forms.widgets.EmailInput()textpassworddateradiocheckbox...''''''form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '123'})# 校验数据是否合法form_obj.is_valid()Falseform_obj = views.MyForm({'username': 'json', 'password': 123, 'email': 'xx@123.com'})form_obj.is_valid() True # 校验合法的数据有哪些form_obj.cleaned_data{'username': 'json', 'password': '123', 'email': 'xx@123.com'}form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '123'})form_obj.is_valid()Falseform_obj.cleaned_data{'username': 'json', 'password': '123'}# 把不合法的数据找出来form_obj.errors{'email': ['输入一个有效的 Email 地址。']}form_obj = views.MyForm({'username': 'json', 'password': 123})form_obj.is_valid()Falseform_obj.errors{'email': ['这个字段是必填项。']}'''def clean_username(self):username = self.cleaned_data.get('username')if '666' in username:self.add_error('username', '只含有666不行')return usernamedef clean_password(self):password = self.cleaned_data.get('password')confirm_password = self.cleaned_data.get('confirm_password')if not confirm_password == password:self.add_error('confirm_password', '两次密码不一致')return self.cleaned_data'''钩子函数(HOOK):在特定的节点自动触发完成响应的操作在forms组件中有两类钩子1.局部钩子:当你需要给单个字段增加校验规则的时候可以使用2.全局钩子:当你需要给多个字段增加校验规则的时候可以使用案例:1.校验用户名中不能含有666 只是校验username字段,局部钩子2.校验密码和确认密码是否一致 password和confirm两个字段全局钩子'''