标签:完整 基本 escape 描述 重构 lin http boolean time
通常情况下,我们需要自己手动在HTML页面中,编写form标签和其内的其它元素。但这费时费力,而且有可能写得不太恰当,数据验证也比较麻烦。有鉴于此,Django在内部集成了一个表单模块,专门帮助我们快速处理表单相关的内容。Django的表单模块给我们提供了下面三个主要功能
Form对象封装了?系列Field和验证规则,Form类都必须直接或间接继承自
django.forms.Form,定义Form有两种方式:
class XXXForm(forms.Form):
pass
class XXX(models.Model):
字段 = models.CharField(max_length=30)
字段 = models.CharField(max_length=20)
class XXXForm(ModelForm):
class Meta:
model = XXX
field = (‘字段‘, ‘字段‘) # 只显示model中指定的字段,显示所有是用‘__all__
models
class Shop(models.Model):
title = models.CharField(‘标题‘
, max_length=30)
content = models.CharField(‘内容‘
, max_length=20)
class Meta:
db_table = ‘T_SHOP‘
ModelForm
class ShopForm(ModelForm):
class Meta:
model = models.Shop
fields = (‘title‘, ‘content‘) # 只显示model中指定的字段
views
from django.shortcuts import render
# Create your views here.
from .forms import ShopForm
def add_shop(request):
if request.method == "POST":
form = ShopForm(request.POST)
if form.is_valid(): # 所有验证都通过
# 处理表单数据
title = form.cleaned_data[‘title‘]
print(title)
# content = form.cleaned_data[‘content‘]
# 保存数据
form.save()
return render(request, ‘shop/add_shop.html‘,
{"shop_form": form})
else:
form = ShopForm()
return render(request, ‘shop/add_shop.html‘, {"shop_form":
form})
模板中使用
<form action=
"{% url ‘add‘ %}" method="post">
{% csrf_token %}
{{ shop_form }}
<input type="submit" value=
"提交"/>
</form>
参数名 | 说明 |
---|---|
required | 给字段添加必填属性,不能空着,若要表示?个字段不是 必需的,设置required=False |
label | label参数用来给字段添加‘?类友好’的提示信息。如果没 有设置这个参数,那么就用字段的首字母大写名字 |
label_suffix | Django默认为上面的label参数后面加个冒号后缀,如果 想?定义,可以使用 label_suffix 参数 |
initial | 为HTML页面中表单元素定义初始值。也就是input元素的 value参数的值 |
widget | 指定渲染Widget时使用的widget类,也就是这个form字 段在HTML页面中是显示为文本输?框?密码输?框?单 选按钮?多选框?还是别的 |
help_text | 该参数用于设置字段的辅助描述文本 |
error_messages | 该参数允许你覆盖字段引发异常时的默认信息。 传递的是 ?个字典,其值为你想覆盖的错误信息 |
validators | 指定?个列表,其中包含了为字段进?验证的函数 |
localize | localize参数帮助实现表单数据输?的本地化。 |
disabled | 设置有该属性的字段在前端页面中将显示为不可编辑状 态。 |
字段名 | 参数 |
---|---|
BooleanField | 默认的Widget:CheckboxInput 空值:False 规范:Python 的True 或 False。 错误信息的键:required |
IntegerField | 默认的Widget:当Field.localize是False时为NumberInput,否则 为TextInput。 空值:None 规范化为:Python 整数或?整数。 验证给定值是?个整数。 允许前导和尾随空格,类似Python的int()函数。 错误信息的键:max_value, invalid, required, min_value |
CharField | 默认的Widget:TextInput 空值:‘‘(?个空字符串) 规范化为:?个Unicode 对象。 如果提供,验证max_length 或 min_length。 否则,所有的输?都是合法的。 错误信息的键:required, max_length, min_length |
ChoiceField | 默认的Widget:Select 空值:‘ ‘(?个空字符串) 规范化为:?个Unicode 对象。 验证给定的值在选项列表中存在。 错误信息的键:required, invalid_choice invalid_choice:错误消息可能包含%(value)s,它将被选择的选项 替换掉。接收?个额外的必选参数:choices?来作为该字段选项的 ?个?元组组成的可迭代对象(例如,列表或元组)或者?个可调 ?对 |
DateField | 默认的Widget:DateInput 空值:None 规范化为:?个Python datetime.date 对象。 错误信息的键:required, invalid input_formats:?个格式的列表,验证给出的值是?个 datetime.date、datetime.datetime 或指定?期格式的字符串。如 果不提供,默认的?期格式:[‘%Y-%m- %d‘,‘%m/%d/%Y‘,‘%m/%d/%y‘] |
DateTimeField | 默认的Widget:DateInput 空值:None 规范化为:?个Python datetime.datetime对象。 错误信息的键:required, invalid input_formats:默认的格式[‘%Y-%m-%d %H:%M:%S‘, ‘%Y-%m- %d %H:%M‘, ‘%Y-%m-%d‘, ‘%m/%d/%Y %H:%M:%S‘,‘%m/%d/%Y %H:%M‘,‘%m/%d/%Y‘, ‘%m/%d/%y %H:%M:%S‘, ‘%m/%d/%y %H:%M‘, ‘%m/%d/%y‘] |
DecimalField | 默认的Widget:当Field.localize是False时为NumberInput,否则 为TextInput。 空值:None 规范化为:Python decimal对象。 错误信息的键: max_whole_digits , max_digits , max_decimal_places , max_value , invalid, required, min_value 可选参数:max_value,min_value:允许的值的范围,需要赋值 decimal.Decimal对象,不能直接给个整数类型。 max_digits:值允许的最?位数(?数点之前和之后的数字总共的位数,前导的零将被删除)。 decimal_places:允许的最??数位。 |
FloatField | 默认的Widget:当Field.localize是False时为NumberInput,否则 为TextInput。 空值:None 规范化为:Float 对象。 验证给定的值是?个浮点数。 错误信息的键:max_value, invalid, required, min_value 可选的参数:max_value和min_value |
EmailField | 默认的Widget:EmailInput 空值:‘‘(?个空字符串) 规范化为:Unicode 对象。 使?正则表达式验证给出的值是?个合 法的邮件地址。 错误信息的键:required, invalid 两个可选的参数?于验证,max_length 和min_length。 |
ImageField | 默认?部件: ClearableFileInput 空值: None 规范化为: UploadedFile 将?件内容和?件名称封装到单个对象 中的对象。 验证?件数据是否已绑定到表单,并且该?件是Pillow可以理解的 图像格式。 错误信息键: required , invalid , missing , empty , invalid_image |
FileField | 默认?部件: ClearableFileInput 空值: None 规范化为: UploadedFile 将?件内容和?件名称封装到单个对象 中的对象。 可以验证?空?件数据已被绑定到表单。 错误信息键: required , invalid , missing , empty , max_length |
ModelChoiceField | 默认的Widget:Select 空值:None 规范化为:?个模型实例。 验证给定的id存在于查询集中。 错误信息的键:required, invalid_choice 可以选择?个单独的模型 对像,适?于表示?个外键字段。 ModelChoiceField默认widet不 适?选择数量很?的情况,在?于100项时应该避免使?它。 可选参数: empty_label:默认情况下,ModelChoiceField使?的上下点击样式 |
名称 | 说明 | 示例 |
---|---|---|
cleaned_data(字典) | 表单中验证通过的?净数 据 |
form.cleaned_data form.cleaned_data.get(‘username‘) |
changed_data | 有变化的字段的列表 | form.changed_data |
fields(字典) | 表单中的字段属性 | form.fiedls[‘username‘] |
is_bound | 表单是否绑定数据 | form.is_bound |
errors(字典) | 错误信息 | form.errors |
is_valid() | 表单中数据是否验证通 过,通过返回True,否 则返回False |
form.is_valid() |
has_changed() | 检查表单数据是否已从初 始数据更改 |
form.has_changed() |
errors.as_json(escape_html=False) | 返回JSON序列化后的错 误信息字典 |
form.errors.as_json() |
对于 label,input 对,还有几个输出选项:
注意,你必须自己提供 table 或 ul 元素。
常用渲染项:
有?的属性包括:{{ field }}
{{ field.label }}
该领域的标签,例如。Email address
{{ field.label_tag }}
字段的标签包含在适当的HTML <label>标记中。这包括表格label_suffix。例
如,默认label_suffix值为冒号:
<label for="id_email">Email address:</label>
{{ field.id_for_label }}
将?于此字段的ID(id_email在上?的示例中)。如果您?动构建标签,则可能
需要使?此代替label_tag。例如,如果你有?些内联JavaScript并且想要避免
硬编码字段的ID,它也很有?。
{{ field.value }}
该字段的值。例如someone@example.com。
{{ field.html_name }}
将在输?元素的名称字段中使?的字段的名称。这会将表单前缀考虑在内,如果已
设置的话。
{{ field.help_text }}
与该字段关联的任何帮助?本。
{{ field.errors }}
输出包含与此字段对应的任何验证错误的a 。您可以使?循环?定义错误的表示。
在这种情况下,循环中的每个对象都是包含错误消息的简单字符串。<ul
class="errorlist">{% for error in field.errors %}
{{ field.is_hidden }}
True如果表单字段是隐藏字段, False则此属性。它作为模板变量并不是特别有
?,但在条件测试中可能很有?,例如:
{% if field.is_hidden %}
{# Do something special #}
{% endif %}
{{ field.field }}
Field来?此BoundField包装的表单类的实例。您可以使?它来访问 Field属
性,例如 。{{ char_field.field.max_length }}
form.as_ul
<form action="/add/" method="post">
{% csrf_token %}
<ul>
{{ form.as_ul }}
</ul>
<input type="submit" value=
"注册?个学?">
</form>
手动渲染
<form action="/add/" method="post">
{% csrf_token %}
<div>
<label for="{{ form.name.id_for_label }}">姓名:</label>
{{ form.name }}
{{ form.name.errors }}
</div>
<div>
<label for="{{ form.sex.id_for_label }}">性别:</label>
{{ form.sex }}
{{ form.sex.errors }}
</div>
<div>
<label for="{{ form.age.id_for_label }}">年龄:</label>
{{ form.age }}
{{ form.age.errors }}
</div>
<input type="submit">
</form>
循环渲染
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
循环隐藏和可见字段
{# Include the hidden fields #}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
可重用的表单模板
# In your form template:
{% include "form_snippet.html" %}
# In form_snippet.html:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
说明
举个栗子
注意事项
class UserFrom(forms.Form):
# ?定义?法(局部钩?),密码必须包含字?和数字
def clean_password(self):
if self.cleaned_data.get(‘password‘).isdigit() or
self.cleaned_data.get(‘password‘).isalpha():
raise ValidationError(‘密码必须包含数字和字?‘)
else:
return self.cleaned_data[‘password‘]
def clean_valid_code(self): # 检验验证码正确;之前?成的验证码保存在了了session中
if self.cleaned_data.get(‘valid_code‘).upper() ==
self.request.session.get(‘valid_code‘):
return self.cleaned_data[‘valid_code‘]
else:
raise ValidationError(‘验证码不正确‘)
# ?定义?法(全局钩?, 检验两个字段),检验两次密码?致;
def clean(self):
if self.cleaned_data.get(‘password‘) !=
self.cleaned_data.get(‘password2‘):
raise ValidationError(‘密码不?致‘)
else:
return self.cleaned_data
# 注意,上?的字典取值?get, 因为假如在clean_password中判断失败,那么没有返回值,最下?的clean?法直接取值就会失败
完整代码
示例代码
class UserFrom(forms.Form):
name = forms.BooleanField(label=‘?户名‘, required=True,error_messages={‘required‘: u‘必选‘})
password = forms.CharField(label= ‘密码‘,widget=forms.PasswordInput(attrs={‘placeholder‘: ‘请输?密码‘}))
confirm_password = forms.CharField(label=‘密码‘,widget=forms.PasswordInput(attrs={‘placeholder‘: ‘请再次输?密
码‘}))
# 下拉框
city = forms.ChoiceField(choices=[(1, ‘上海‘), (2, ‘北京‘,), (3, ‘?州‘)])
create_date = forms.DateField(label= ‘选择时间‘, input_formats=[‘%Y-%m-%d‘])
price = forms.DecimalField(label=‘价格‘ , max_digits=10,decimal_places=2)
head = forms.FileField(allow_empty_file=True)
img = forms.ImageField(allow_empty_file=True)
email = forms.EmailField(required=False,
error_messages={‘required‘: u‘邮箱不能为空‘ ,‘invalid‘: u‘邮箱格式错误‘},
widget=forms.TextInput(
attrs={‘class‘: "form-control",‘placeholder‘: u‘邮箱‘}))
address=forms.ModelChoiceField(queryset=models.Address.objects.filter(uid
=2), empty_label=None , to_field_name=None)
def clean_password(self):
if self.cleaned_data.get(‘password‘).isdigit() or
self.cleaned_data.get(‘password‘).isalpha():
raise ValidationError(‘密码必须包含数字和字?‘)
else:
return self.cleaned_data[‘password‘]
def clean_valid_code(self):
if self.cleaned_data.get(‘valid_code‘).upper() ==
self.request.session.get(‘valid_code‘):
return self.cleaned_data[‘valid_code‘]
else:
raise ValidationError(‘验证码不正确‘)
def clean(self):
if self.cleaned_data.get(‘password‘) !=
self.cleaned_data.get(‘confirm_password‘):
raise ValidationError(‘密码不?致‘)
else:
return self.cleaned_data
#-----------------------------------------models.py
from django.db import models
class Info(models.Model):
name = models.CharField(max_length=64)
sex = models.CharField(max_length=64)
birthday = models.CharField(max_length=64)
age=models.CharField(max_length=64)
qualification=models.CharField(max_length=64)
job=models.CharField(max_length=64)
email=models.CharField(max_length=64,default=‘‘)
class Hobby(models.Model):
item=models.CharField(max_length=64)
#-----------------------------------------form.py
from django import forms
from app01 import models
from django.core.exceptions import ValidationError
class InfoForm(forms.Form):
def validate_name(value):
try:
models.Info.objects.get(name=value)
raise ValidationError(‘%s 的信息已经存在!‘%value)
except models.Info.DoesNotExist:
pass
sex_choice=((0,‘男‘),
(1,‘?‘))#select的数据可以像这样写,也可以在另外?张表中动
态去拿
name = forms.CharField(validators=[validate_name],label=‘姓
名‘,error_messages={‘required‘:‘必填‘})
age = forms.CharField(label=‘年龄‘,error_messages={‘required‘:‘必
填‘})
# sex = forms.CharField(label=‘性别‘,error_messages=
{‘required‘:‘必填‘,},)
sex=forms.IntegerField(widget=forms.widgets.Select(choices=sex_choice
,
attrs={‘class‘:‘setform2‘} ))
birthday = forms.CharField(label=‘??‘,error_messages=
{‘required‘:‘必填‘})
qualification = forms.CharField(label=‘学历‘,error_messages=
{‘required‘:‘必填‘},widget=forms.TextInput(attrs=
{‘class‘:‘formset‘,‘placeholder‘:‘本科‘ }))
email=forms.EmailField(max_length=100,min_length=10)
job = forms.CharField(label=‘?作‘,error_messages={‘required‘:‘必
填‘})
def __init__(self,*args,**kwargs):
super(Info_form,self).__init__(*args,**kwargs)
self.fields[‘hobby‘]=forms.CharField(widget=forms.widgets.Select(choi
ces=models.Hobby.objects.values_list(‘id‘,‘item‘)))
#-----------views.py
from django.shortcuts import render,HttpResponse
def add_info(req):
if req.method==‘POST‘:
Info_form_obj=Info_form(req.POST)
if Info_form_obj.is_valid():
Info.objects.create(name=Info_form_obj.cleaned_data[‘name‘],
age=Info_form_obj.cleaned_data[‘age‘],
sex=Info_form_obj.cleaned_data[‘sex‘],
birthday=Info_form_obj.cleaned_data[‘birthday‘],
qualification=Info_form_obj.cleaned_data[‘qualification‘],
job=Info_form_obj.cleaned_data[‘job‘]
)
return HttpResponse(‘添加成功!‘)
else:
error_obj=Info_form_obj.errors
print(‘***************‘)
print(type(error_obj))#<class
‘django.forms.utils.ErrorDict‘>
print(error_obj[‘name‘][0])#必填
print(error_obj.get(‘age‘))#<ul class="errorlist"><li>必
填</li></ul>
return render(req,‘add_info.html‘,
{‘form_obj‘:Info_form_obj,‘error_obj‘:error_obj})
Info_form_obj=Info_form()
return render(req,‘add_info.html‘,{‘form_obj‘:Info_form_obj})
#------add_info.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>添加个?信息</title>
<style>
.formset {
color: rebeccapurple;
border: dashed cadetblue;
}
</style>
</head>
<body>
<form action=
"{% url ‘add_info‘ %}" method="post">
<p>姓名{{ form_obj.name }}{{ error_obj.name.0 }}</p>
<p>年龄{{ form_obj.age }}{{ error_obj.age.0 }}</p>
<p>??{{ form_obj.birthday }}{{ error_obj.birthday.0 }}</p>
<p>?作{{ form_obj.job }}<span>{{ error_obj.job }}</span>
</p>
<p>学历{{ form_obj.qualification }}<span>{{
error_obj.qualification }}</span></p>
<p>性别{{ form_obj.sex }}<span>{{ error_obj.sex }}</span>
</p>
<p>邮箱{{ form_obj.email }}<span>{{ error_obj.email }}
</span></p>
<p>爱好{{ form_obj.hobby }}<span>{{ error_obj.hobby }}
</span></p>
{{ form_obj.as_p }}
<input type="submit" value=
"提交"><br>
{% csrf_token %}
</form>
</body>
</html>
标签:完整 基本 escape 描述 重构 lin http boolean time
原文地址:https://www.cnblogs.com/williamweson/p/13614719.html