一、使用说明
1. 创建一个forms.py的文件,放在指定的app当中,然后在里面写表单.
2. 表单是通过类实现的,继承自forms.Form,然后在里面定义要验证的字段.
3. 在表单中,创建字段跟模型是一模一样的,但是没有null=True或者blank=True等这几种参数了,有的参数是required=True/False.
4. 使用is_valid()方法可以验证用户提交的数据是否合法,而且HTML表单元素的name必须和django中的表单的name保持一致,否则匹配不到.
5. is_bound属性:用来表示form是否绑定了数据,如果绑定了,则返回True,否则返回False.
6. cleaned_data:这个是在is_valid()返回True的时候,保存用户提交上来的数据.
二、表单说明
示例代码:
from django import forms
class LoginForm(forms.Form):
username = forms.CharField(max_length=16, min_length=8, strip=True, error_messages={
"max_length": "用户名长度超过16位",
"min_length": "用户名长度小于8位",
"required": "用户名不能为空"
})
password = forms.CharField(strip=True, error_messages={
"required": "密码不能为空"
})
forms模块中的字段样式:
__all__ = ( 'Field', 'CharField', 'IntegerField', 'DateField', 'TimeField', 'DateTimeField', 'DurationField', 'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField', 'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField', 'ComboField', 'MultiValueField', 'FloatField', 'DecimalField', 'SplitDateTimeField', 'GenericIPAddressField', 'FilePathField', 'SlugField', 'TypedChoiceField', 'TypedMultipleChoiceField', 'UUIDField', )
forms模块中用于验证的字段参数:
Field required=True#请求不能为空 widget=None#HTML插件 label=None#用于生成lable标签或显示内容 initial=None#初始值 help_text=''#帮助信息(在标签旁边显示) error_messages=None#(错误信息{‘required’:'不能为空',‘invalid’:‘格式错误’}) show_hidden_initial=False#是否在当前插件后面加一个隐藏的并且有默认值的插件(可用于检验两次输入是否一致) validators=()#自定义验证规则 localize=False#是否支持本地化 disabled=False#是否可以编辑 label_suffix=None#label内容后缀 CharField(Field) max_length=None, 最大长度 min_length=None, 最小长度 strip=True 是否移除用户输入空白 IntegerField(Field) max_value=None, 最大值 min_value=None, 最小值 FloatField(IntegerField) ... DecimalField(IntegerField) max_value=None, 最大值 min_value=None, 最小值 max_digits=None, 总长度 decimal_places=None, 小数位长度 BaseTemporalField(Field) input_formats=None 时间格式化 DateField(BaseTemporalField) 格式:2015-09-01 TimeField(BaseTemporalField) 格式:11:12 DateTimeField(BaseTemporalField)格式:2015-09-01 11:12 DurationField(Field) 时间间隔:%d %H:%M:%S.%f ... RegexField(CharField) regex, 自定制正则表达式 max_length=None, 最大长度 min_length=None, 最小长度 error_message=None, 忽略,错误信息使用 error_messages={'invalid': '...'} EmailField(CharField) ... FileField(Field) allow_empty_file=False 是否允许空文件 ImageField(FileField) ... 注:需要PIL模块,pip3 install Pillow 以上两个字典使用时,需要注意两点: - form表单中 enctype="multipart/form-data" - view函数中 obj = MyForm(request.POST, request.FILES) URLField(Field) ... BooleanField(Field) ... NullBooleanField(BooleanField) ... ChoiceField(Field) ... choices=(), 选项,如:choices = ((0,'上海'),(1,'北京'),) required=True, 是否必填 widget=None, 插件,默认select插件 label=None, Label内容 initial=None, 初始值 help_text='', 帮助提示 ModelChoiceField(ChoiceField) ... django.forms.models.ModelChoiceField queryset, # 查询数据库中的数据 empty_label="---------", # 默认空显示内容 to_field_name=None, # HTML中value的值对应的字段 limit_choices_to=None # ModelForm中对queryset二次筛选 ModelMultipleChoiceField(ModelChoiceField) ... django.forms.models.ModelMultipleChoiceField TypedChoiceField(ChoiceField) coerce = lambda val: val 对选中的值进行一次转换 empty_value= '' 空值的默认值 MultipleChoiceField(ChoiceField) ... TypedMultipleChoiceField(MultipleChoiceField) coerce = lambda val: val 对选中的每一个值进行一次转换 empty_value= '' 空值的默认值 ComboField(Field) fields=() 使用多个验证,如下:即验证最大长度20,又验证邮箱格式 fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),]) MultiValueField(Field) PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用 SplitDateTimeField(MultiValueField) input_date_formats=None, 格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y'] input_time_formats=None 格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'] FilePathField(ChoiceField) 文件选项,目录下文件显示在页面中 path, 文件夹路径 match=None, 正则匹配 recursive=False, 递归下面的文件夹 allow_files=True, 允许文件 allow_folders=False, 允许文件夹 required=True, widget=None, label=None, initial=None, help_text='' GenericIPAddressField protocol='both', both,ipv4,ipv6支持的IP格式 unpack_ipv4=False 解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用 SlugField(CharField) 数字,字母,下划线,减号(连字符) ... UUIDField(CharField) uuid类型 ...
自定义错误信息:
在字段参数中有一个error_messages的参数,其值是一个字典,键表示不符合的字段验证名,值表示自定义的错误信息
from django import forms class LoginForm(forms.Form): username = forms.CharField(max_length=16, min_length=8, strip=True, error_messages={ "max_length": "用户名长度超过16位", "min_length": "用户名长度小于8位", "required": "用户名不能为空" }) password = forms.CharField(strip=True, error_messages={ "required": "密码不能为空" })
三、使用表单
注:虽然form可以生成前端页面,但这个功能实际用的少,主要是是用form表单的验证功能.
from .forms import RegisterFrom from .models import User def register(request): if request.method == 'GET': form = RegisterFrom() return render(request,'ts22/register.html', context={'form':form}) elif request.method == 'POST': form = RegisterFrom(request.POST) if form.is_valid(): username = form.cleaned_data.get('username') password = form.cleaned_data.get('password') password_repeat = form.cleaned_data.get('password_repeat') email = form.cleaned_data.get('email') if password == password_repeat: user = User.objects.create(username=username, password=password,email=email) return HttpResponse('注册成功!') else: return HttpResponse('注册失败!') else: return HttpResponse('注册失败!')
# Create your views here. class LoginView(views.View): def get(self, request): return render(self.request, 'user/login.html') def post(self, request): # 将提交的参数传进表单中,逐一比较验证 form = LoginForm(request.POST) print(request.POST) print(form) # 表单验证通过 if form.is_valid(): username = form.cleaned_data.get("username") password = form.changed_data.get("password") user_info = User.objects.filter(username=username).first() if user_info.get("username", None) and (user_info.get("password") == password): return HttpResponse("登陆成功!") else: return HttpResponse("用户名不存在!") # 表单验证失败,获取失败的信息进行处理 else: # <tr><th><label for="id_username">Username:</label></th><td><ul class="errorlist"><li>用户名长度小于8位</li></ul><input type="text" name="username" value="admin" maxlength="16" minlength="8" required id="id_username"></td></tr> # <tr><th><label for="id_password">Password:</label></th><td><input type="text" name="password" value="asd2743075" required id="id_password"></td></tr> # <ul class="errorlist"><li>username<ul class="errorlist"><li>用户名长度小于8位</li></ul></li></ul> print(form.errors) # {'username': [ValidationError(['用户名长度小于8位'])]} print(form.errors.as_data()) # {"username": [{"message": "u7528u6237u540du957fu5ea6u5c0fu4e8e8u4f4d", "code": "min_length"}]} print(form.errors.as_json()) return HttpResponse(form.errors.as_json())