form 组件
Posted TianTianLi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了form 组件相关的知识,希望对你有一定的参考价值。
- 初始form组件
Django的Form主要具有一下几大功能:
- 生成html标签
- 验证用户数据(显示错误信息)
- HTML Form提交保留上次提交数据
- 初始化页面显示内容
- 验证功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form method="post" action="/form/">
<P><input type="text" name="username">{{ obj.errors.username.0 }}</P>
<P><input type="password" name="pwd">{{ obj.errors.pwd.0 }}</P>
<P><input type="text" name="age">{{ obj.errors.age.0 }}</P>
<P><input type="text" name="email">{{ obj.errors.email.0 }}</P>
<p><input type="submit"></p>
</form>
</body>
</html>
from django import forms from django.forms import fields class RegisterForm(forms.Form): username = forms.CharField(max_length=20, min_length=6, required=True, error_messages={ \'required\':\'用户名不能为空\', \'max_length\': \'最大长度20\', \'min_length\': \'最小长度6\', }) pwd = forms.CharField(max_length=20, min_length=6, required=True) age = forms.IntegerField(required=True) email = forms.EmailField(required=True,error_messages={ \'invalid\':\'格式错误\' })
from django.shortcuts import render from myform.cfrom import RegisterForm # Create your views here. def form(request): if request.method == \'GET\': return render(request, \'forms/index.html\') else: print(request.POST) obj = RegisterForm(request.POST) if obj.is_valid(): print(obj.cleaned_data) else: print(obj.errors) return render(request, \'forms/index.html\',{\'obj\':obj})
- 生成input标签功能
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="post" action="/form/" novalidate> <P>{{ form_obj.username }}{{ form_obj.errors.username.0 }}</P> <P>{{ form_obj.pwd }}{{ form_obj.errors.pwd.0 }}</P> <P>{{ form_obj.age }}{{ form_obj.errors.age.0 }}</P> <P>{{ form_obj.email }}{{ form_obj.errors.email.0 }}</P> <p><input type="submit"></p> </form> </body> </html>
from django.shortcuts import render
from myform.cfrom import RegisterForm
# Create your views here.
def form(request):
if request.method == \'GET\':
form_obj = RegisterForm()
return render(request, \'forms/index.html\', {\'form_obj\': form_obj})
else:
print(request.POST)
form_obj = RegisterForm(request.POST)
# obj = RegisterForm(request.POST)
if form_obj.is_valid():
print(form_obj.cleaned_data)
else:
print(form_obj.errors)
return render(request, \'forms/index.html\', { \'form_obj\': form_obj})
form类
from django import forms from django.forms import fields from django.forms import widgets class RegisterForm(forms.Form): username = fields.CharField( max_length=20, min_length=6, required=True, widget=widgets.TextInput(attrs={\'v\': \'v1\', \'class\': \'c1\'}), initial=\'用户名\', label=\'用户名\', help_text=\'字母、数字、下划线\', disabled=False, label_suffix=\':\', error_messages={ \'required\': \'用户名不能为空\', \'max_length\': \'最大长度20\', \'min_length\': \'最小长度6\', }, ) pwd = fields.CharField( max_length=20, min_length=6, required=True, label=\'密码\', widget=widgets.PasswordInput ) age = fields.IntegerField( required=True, max_value=200, min_value=0, label=\'年龄\', ) email = fields.EmailField(required=True, error_messages={ \'invalid\': \'格式错误\' }, label=\'邮箱\', ) # 单选select city = fields.ChoiceField( choices=[ (1, \'中国\'), (2, \'美国\'), (3, \'日本\'), ], initial=1, label=\'国籍\', ) # 多选select hobby = fields.MultipleChoiceField( choices=[ (1, \'音乐\'), (2, \'把妹\'), (3, \'约妹\'), ], initial=[1, 3] ) def __init__(self, *args, **kwargs): super(RegisterForm, self).__init__(*args, **kwargs) # 必须在self.fieLds上面 self.fields[\'hobby\'].widget.choices = ((1, \'嗨\'), (2, \'嗨嗨\'),) # 或 # self.fields[\'hobby\'].widget.choices = models.Classes.objects.all().value_list(\'id\', \'caption\') # 文件 img = fields.FileField( label=\'图片\' ) # 单选的checkbox chk = fields.CharField( widget=widgets.CheckboxInput( attrs={\'v\': \'v1\', \'class\': \'c1\'} ), label=\'居住地\' ) # 多选checkbox,值为列表 dchk = fields.MultipleChoiceField( initial=[2, 1], choices=((1, \'上海\'), (2, \'北京\'),), widget=widgets.CheckboxSelectMultiple, label=\'曾住地\' ) # 单选的radio rad = fields.CharField( widget=widgets.Radioselect(choices=((1, \'男\'), (2, \'女\'),)), label=\'性别\' ) # 单radio,值为字符串 rad1 = fields.ChoiceField( choices=((1, \'有\'), (2, \'无\'),), initial=2, widget=widgets.RadioSelect( attrs={\'class\': \'ll\'} ), label=\'媳妇\' )
注意:
若是要生成 下拉菜单, 尽量不要使用 fields.ChoiceField, 实际在提交的时候总是验证错误。建议使用以下方式生成:
from django import forms from django.forms import fields from django.forms import widgets from app01 import models def get_column_list(): choices = models.ArticleColumn.objects.all().values_list(\'id\', \'column\') return choices class ArticlePostForm(forms.Form): choice = get_column_list() def __init__(self, *args, **kwargs): super(ArticlePostForm, self).__init__(*args, **kwargs) # 必须在self.fieLds上面 self.fields[\'column\'].widget.choices = get_column_list() title = fields.CharField( required=True, error_messages={ \'required\': \'标题为空...\' } ) column = forms.CharField( required=True, widget=widgets.Select ) body = fields.CharField( required=True, widget=widgets.Textarea, error_messages={ \'required\': \'内容为空...\' } )
验证流程图:
流程详解
- 函数full_clean()依次调用每个field的clean()函数,该函数针对field的max_length,unique等约束进行验证,如果验证成功则返回值,否则抛出ValidationError错误。如果有值返回,则放入form的cleaned_data字典中。
- 如果每个field的内置clean()函数没有抛出ValidationError错误,则调用以clean_开头,以field名字结尾的自定义field验证函数。验证成功和失败的处理方式同步骤1。
- 最后,调用form的clean()函数——注意,这里是form的clean(),而不是field的clean()——如果clean没有错误,那么它将返回cleaned_data字典。
- 如果到这一步没有ValidationError抛出,那么cleaned_data字典就填满了有效数据。否则cleaned_data不存在,form的另外一个字典errors填上验证错误。在template中,每个field获取自己错误的方式是:{{ form.username.errors }}。
- 最后,如果有错误is_valid()返回False,否则返回True。
注意一点:自定义验证机制时:clean()和clean_<field>&()的最后必须返回验证完毕或修改后的值.
也就是说,自定义clean_fields 时,返回的是验证过的字段数据。自定义clean() 是在最后一步,要返回完整的clean_data.
# 自定义验证 验证password def clean_password(self): user_data = cleaned_data.get(\'password\') if user_data == \'XXX\': raise forms.ValidationError(u\'密码太简单了\') return user_data
# 验证选择婚姻是否正确 def clean_marry(self): data_list = self.cleaned_data[\'marry\'] if len(data_list) == 2: if \'0\' and \'1\' in data_list: raise forms.ValidationError(\'男女选择有误!\') elif \'2\' and \'3\' in data_list: raise forms.ValidationError(\'婚姻选择有误!\') else: return data_list else: raise forms.ValidationError(\'请选择男女和婚姻!\')
def clean(self): cleaned_data = self.cleaned_data pwd = cleaned_data[\'pwd\'] pwd2 = cleaned_data[\'pwd2\'] print(pwd,pwd2) if pwd != pwd2: raise forms.ValidationError(\'二次输入密码不匹配\') return cleaned_data #注意此处一定要return clean_data,否则会报错
自定义验证规则
方式一:
rom django.forms import Form from django.forms import widgets from django.forms import fields from django.core.validators import RegexValidator class MyForm(Form): user = fields.CharField( validators=[RegexValidator(r\'^[0-9]+$\', \'请输入数字\'), RegexValidator(r\'^159[0-9]+$\', \'数字必须以159开头\')], )
方式二:
def mobile_validate(value): mobile_re = re.compile(r\'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$\') if not mobile_re.match(value): raise ValidationError(\'手机号码格式错误\') class PublishForm(Form): title = fields.CharField(max_length=20, min_length=5, error_messages={\'required\': \'标题不能为空\', \'min_length\': \'标题最少为5个字符\', \'max_length\': \'标题最多为20个字符\'}, widget=widgets.TextInput(attrs={\'class\': "form-control", \'placeholder\': \'标题5-20个字符\'})) # 使用自定义验证规则 phone = fields.CharField(validators=[mobile_validate, ], error_messages={\'required\': \'手机不能为空\'}, widget=widgets.TextInput(attrs={\'class\': "form-control", \'placeholder\': u\'手机号码\'}))
参考文档:http://www.cnblogs.com/wupeiqi/articles/6144178.html
class RegistrationForm(forms.Form): username = fields.CharField( required=True, error_messages={ \'required\': \'输入用户名...\' } ) email = fields.EmailField( required=True, error_messages={ \'required\': \'输入邮箱...\', \'invalid\':\'格式错误...\' } ) password = fields.CharField( required=True, min_length=6, label=\'密码\', widget=widgets.PasswordInput, error_messages={ \'required\': \'输入密码...\', \'min_length\': \'最小长度为6...\' } ) password_again = fields.CharField( required=True, widget=widgets.PasswordInput, label=\'确认密码\', error_messages = { \'required\': \'输入密码...\', } ) def clean_username(self): username = self.cleaned_data[\'username\'] ret = UserInfo.objects.filter(username=username) if ret.exists(): raise forms.ValidationError(\'用户名已存在...\') return username def clean(self): clean_data = self.cleaned_data if not self.errors: password1 = clean_data[\'password\'] password2 = clean_data[\'password_again\'] if password1 != password2: raise forms.ValidationError(\'两次密码不一致...\') return clean_data
以上是关于form 组件的主要内容,如果未能解决你的问题,请参考以下文章
maven web项目的web.xml报错The markup in the document following the root element must be well-formed.(代码片段