django 表单
django 表单
django表单的作用
在Django中的表单,主要有两个功能:
- 渲染表单模板(只有前后端不分离时才有可能使用,一般情况不用)。
- 表单验证数据是否合法。
验证数据基本用法
- app/forms.py中定义表单验证类,根据前台提交的每个字段定义对应的属性进行验证。
- 实例化表单验证类(传入前台提交的参数)。
- 通过form.is_valid()校验提交的参数。
- 如果校验成功,则从form.cleaned_data中获取前台提交的参数。
- 如果校验失败,则从form.errors中获取错误信息,form.errors获取的html格式的错误信息,可以通过form.errors.get_json_data()获取字典格式的错误信息。

自定义错误信息:
通过Field的error_messages属性定义每个校验的错误信息。如下:

常用的Field
CharField:
用来接收文本。
参数:
max_length:这个字段值的最大长度。
min_length:这个字段值的最小长度。
required:这个字段是否是必须的。默认是必须的。
error_messages:在某个条件验证失败的时候,给出错误信息。
EmailField:
用来接收邮件,会自动验证邮件是否合法。
错误信息的key:required、invalid。
FloatField:
用来接收浮点类型,并且如果验证通过后,会将这个字段的值转换为浮点类型。
参数:
max_value:最大的值。
min_value:最小的值。
required:这个字段是否是必须的。默认是必须的。
错误信息的key:required、invalid、max_value、min_value。
IntegerField:
用来接收整形,并且验证通过后,会将这个字段的值转换为整形。
参数:
max_value:最大的值。
min_value:最小的值。
错误信息的key:required、invalid、max_value、min_value。
URLField:
用来接收url格式的字符串。
错误信息的key:required、invalid。
常用验证器
在验证某个字段的时候,可以传递一个validators参数用来指定验证器,进一步对数据进行过滤。
很多验证器其实通过Field或者一些参数就可以指定。比如EmailValidator,可以通过EmailField来指定,比如MaxValueValidator,可以通过max_value参数来指定。
- MaxValueValidator:验证最大值。
- MinValueValidator:验证最小值。
- MinLengthValidator:验证最小长度。
- MaxLengthValidator:验证最大长度。
- EmailValidator:验证是否是邮箱格式。
- URLValidator:验证是否是URL格式。
- RegexValidator:如果还需要更加复杂的验证,那么可以通过正则表达式的验证器:RegexValidator。
如下: 验证手机号码的正则表达式验证器。

自定义验证字段的方法
在注册的表单验证中,我们想要验证手机号码是否已经被注册过了,那么这时候就需要在数据库中进行判断才知道。
对某个字段进行自定义的验证方式是,定义一个方法,这个方法的名字定义规则是:clean_fieldname。如果验证失败,那么就抛出一个验证错误。
校验单个属性
如下:定义clean_属性名的方法针对单个属性进行校验。

校验多个属性
如下: 重写父类的clean方法。

提取错误信息
django原生的错误信息展示比较混乱,需要提取其中需要的信息返回给前端。
在表单类中定义get_error_msg方法(可以定义一个父类,将get_error_msg写在父类中,所有的表单类都继承这个父类)
def get_error_msg(self):
errors = self.errors.get_json_data()
err_msg = {}
for key, msg_list in errors.items():
item_msg = []
for msg in msg_list:
item_msg.append(msg["message"])
err_msg[key] = item_msg
return err_msg

ModelForm
如果一个表单中的字段和最终要保存到数据库的字段基本一致,可以考虑使用ModelForm。
如下:
模型Article
from django.db import models
from django.core import validators
class Article(models.Model):
title = models.CharField(max_length=10,validators=[validators.MinLengthValidator(limit_value=3)])
content = models.TextField()
author = models.CharField(max_length=100)
category = models.CharField(max_length=100)
create_time = models.DateTimeField(auto_now_add=True)
在写表单的时候,就不需要把Article模型中所有的字段都一个个重复写一遍。
from django import forms
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = "__all__"
ArticleForm继承自forms.ModelForm。
定义Meta类,在Meta类中指定了model=Article,以及fields=“all”,这样就可以将Article模型中所有的字段都复制过来,进行验证。
验证指定字段
如果只想针对其中几个字段进行验证,那么可以给fields指定一个列表,将需要的字段写进去。比如只想验证title和content,那么可以使用以下代码实现:
from django import forms
class MyForm(forms.ModelForm):
class Meta:
model = Article
fields = ['title','content']
如果要验证的字段比较多,只是除了少数几个字段不需要验证,那么可以使用exclude来代替fields。比如我不想验证category,那么示例代码如下:
class MyForm(forms.ModelForm):
class Meta:
model = Article
exclude = ['category']
如果需要针对字段进行更复杂的验证,那么根使用普通Form是一样的,在Form中定义clean_字段名的校验方法,或者多个字段的联合校验可以重写clean方法。
自定义错误消息
使用ModelForm,因为字段都不是在表单中定义的,而是在模型中定义的,因此一些错误消息无法在字段中定义。
那么这时候可以在Meta类中,定义error_messages,然后把相应的错误消息写到里面去。
class MyForm(forms.ModelForm):
class Meta:
model = Article
exclude = ['category']
error_messages = {
'title':{
'max_length': '最多不能超过10个字符!',
'min_length': '最少不能少于3个字符!'
},
'content': {
'required': '必须输入content!',
}
}
save方法
ModelForm的save方法,可以在验证完成后直接调用save方法,就可以将这个数据保存到数据库中了,不需要再从cleaned_data中取出每一个字段再去实例化模型对象,调用模型对象的save方法。
form = MyForm(request.POST)
if form.is_valid():
form.save()
return HttpResponse('succes')
else:
print(form.get_errors())
return HttpResponse('fail')
在调用save方法的时候,如果传入一个commit=False,那么只会生成这个模型的对象,而不会把这个对象真正的插入到数据库中。比如表单上验证的字段没有包含模型中所有的字段,这时候就可以先创建对象,再根据填充其他字段,把所有字段的值都补充完成后,再保存到数据库中。
form = MyForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.category = 'Python'
article.save()
return HttpResponse('succes')
else:
print(form.get_errors())
return HttpResponse('fail')

本文介绍了Django表单的主要作用,包括渲染模板和数据验证。详细讲解了表单验证的基本用法,如定义表单验证类、校验数据、提取错误信息。此外,还讨论了常用的Field类型,如CharField、EmailField等,并展示了如何自定义验证字段的方法。同时,文章提到了ModelForm的使用,包括验证指定字段、自定义错误消息和save方法的运用。

3792

被折叠的 条评论
为什么被折叠?



