Form表单中常用的Field
- CharField:用来接收文本类型。
参数: max_length:这个字段值的最大长度。 min_length:这个字段值的最小长度。 required:这个字段是否是必须的。默认是必须的。 error_messages:在某个条件验证失败的时候,给出错误信息。
- EmailField:用来接收邮件地址类型,会自动验证邮件地址是否合法。
参数: error_messages:在某个条件验证失败的时候,给出错误信息。 错误信息的key有:required、invalid。
- FloatField:用来接收浮点类型,如果验证通过后,会自动将这个字段的值转换为浮点类型。
参数: max_value:限定最大值。 min_value:限定最小值。 error_messages:在某个条件验证失败的时候,给出错误信息。 错误信息的key有:required、invalid、max_value、min_value。
- IntegerField:用来接收整形类型,验证通过后,会将这个字段的值转换为整形。
参数: max_value:最大的值。 min_value:最小的值。 error_messages:在某个条件验证失败的时候,给出错误信息。 错误信息的key有:required、invalid、max_value、min_value。
- URLField:用来接收url格式的字符串。
参数: error_messages:在某个条件验证失败的时候,给出错误信息。 错误信息的key有:required、invalid。
Form表单常用验证器
在验证某个字段的时候,可以传递一个validators参数用来指定验证器,对数据进行进一步的过滤。验证器有很多,但是很多验证器我们其实已经通过这个Field或者一些参数就可以指定了。比如EmailValidator,我们可以通过EmailField来指定,比如MaxValueValidator,我们可以通过max_value参数来指定。如果还需要更加复杂的验证,我们可以通过正则表达式的验证器RegexValidator。
MaxValueValidator:验证最大值。
MinValueValidator:验证最小值。
MinLengthValidator:验证最小长度。
MaxLengthValidator:验证最大长度。
EmailValidator:验证是否是邮箱格式。
URLValidator:验证是否是URL格式。
RegexValidator:表达式的验证器。
自定义验证
- 如果不能通过长度和正则表达式等验证器去验证,比如在注册的表单验证中,我们想要验证手机号码是否已经被注册过,这时候就需要在数据库中进行判断才知道。
- 对某个字段进行自定义的验证方式是,定义一个方法,方法的命名规则是:clean_fieldname。如果验证失败,则抛出一个验证错误。例如要验证用户表中手机号码之前是否在数据库中存在,那么可以通过以下代码实现
class RegisterForm(forms.Form): telephone = forms.IntegerField(label='手机号', validators=[validators.RegexValidator("^1[3|4|5|7|8][0-9]{9}$")], error_messages={ 'invalid': '手机号码格式不正确'}) def clean_telephone(self): telephone = self.cleaned_data.get('telephone') result = User.objects.filter(telephone=telephone).exists() if result: raise forms.ValidationError("手机号码已经存在!") return telephone
提取错误信息
如果某个验证失败了,我们需要给前端传送一些错误,这时候我们可以通过以下属性来获取:
- form.errors:这个属性获取的错误信息是一个包含了html标签的错误信息。
- form.errors.get_json_data():这个方法获取到的是一个字典类型的错误信息。将某个字段的名字作为key,错误信息作为值的一个字典。
- form.as_json():这个方法是将
form.get_json_data()
返回的字典dump成json格式的字符串,方便进行传输。
上述方法获取的字段的错误信息,都是一个比较复杂的数据。比如以下:
{'telephone': [{'message': '手机号码格式不正确', 'code': 'invalid'}]}
如果想把错误信息放在一个列表中,而不要放在一个字典中。这时候我们可以定义一个方法,把得到的错误数据整理一下。
def get_errors(self):
errors = self.errors.get_json_data()
new_errors = {
}
for key,message_dicts in errors.items():
messages = []
for message in message_dicts:
messages.append(message['message'])
new_errors[key] = messages
return new_errors
结果显示为{'telephone': ['手机号码格式不正确']}
Django中Form表单的使用流程
模拟一个注册流程
- 1、新建forms.py文件,用于创建表单类
- 2、在forms.py里创建一个表单类(RegisterForm),继承forms.Form
from django import forms from django.core import validators from .models import User class RegisterForm(forms.Form): username = forms.CharField(label='用户名', max_length=5, min_length=3) pwd1 = forms.CharField(label='密码', validators=[validators.RegexValidator("^[A-Za-z0-9]{8,16}$", message='密码格式不正确')]) pwd2 = forms.CharField(label='确认密码') telephone = forms.IntegerField(label='手机号', validators=[validators.RegexValidator("^1[3|4|5|7|8][0-9]{9}$")], error_messages={ 'invalid': '手机号码格式不正确'}) email = forms.EmailField(label='邮箱') is_student = forms.BooleanField(required=False, label='学生') def clean_telephone(self): telephone = self.cleaned_data.get('telephone') result = User.objects.filter(telephone=telephone).exists() if result: raise forms.ValidationError("手机号码已经存在!") return telephone def clean(self): pwd1 = self.cleaned_data.get('pwd1') pwd2 = self.cleaned_data.get('pwd2') if pwd2 != pwd1: raise forms.ValidationError("两次密码输入不一致") def get_errors(self): errors = self.errors.get_json_data() new_errors = { } for key, message_dicts in errors.items(): messages = [] for message in message_dicts: messages.append(message['message']) new_errors[key] = messages return new_errors
- 3、在views.py文件里定义一个视图类,创建get和post方法
from django.shortcuts import render from django.views import View from .forms import RegisterForm class FormView(View): def get(self, request): form = RegisterForm() return render(request, 'form.html', { 'form': form, 'result': ''}) def post(self, request): form = RegisterForm(request.POST) if form.is_valid(): username = form.cleaned_data.get('username') pwd1 = form.cleaned_data.get('pwd1') telephone = form.cleaned_data.get('telephone') email = form.cleaned_data.get('email') is_student = form.cleaned_data.get('is_student') print(username, pwd1, telephone, email, is_student) return render(request, 'form.html', { 'form': form, 'result': 'submit success'}) else: form = RegisterForm(request.POST) print(form.get_errors()) return render(request, 'form.html', { 'form': form, 'result': 'submit failed'})
- 4、在urls.py文件里配置url
from django.urls import path from . import views urlpatterns = [ path('', views.FormView.as_view(), name='user'), ]
- 5、创建html模板文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册</title> </head> <body> <form action="", method="post"> <table> { { form.as_table }} <tr> <td></td> <td><input type="submit" value="提交"></td> </tr> <tr><td>{ { result }}</td></tr> </table> </form> </body> </html>