Forms#-表单基础
在Django中创建表单
-
表单
# forms.py from django import forms class NameForm(forms.Form): your_name = forms.CharField(label='Your name', max_length=100)
这里需要注意的是:
-
label
参数可以被忽略,Django会自动为该列生成一个label(其实此处label
指定的名称同Django自动生成的名称是一样的) -
max_length
在HTML的表单中指定了对应列的maxlength
属性,同时也会对浏览器表单提交的内容长度进行合理化处理 - 每个Form实例对象有一个
is_valid()
方法,当表单所有列都符合要求时,调用该方法会:- 返回True
- 将表单数据存入
cleaned_data
属性中
最终上述Django中创建的表单在HTML中的显示为:
<label for="your_name">Your name: </label> <input id="your_name" type="text" name="your_name" maxlength="100" required />
注意:
- 此处并不包含
<form>
标签 - 亦不包含提交按钮
上边两项都需要自己手动在HTML中添加
-
-
视图函数
from django.shortcuts import render from django.http import HttpResponseRedirect from .forms import NameForm def get_name(request): # if this is a POST request we need to process the form data if request.method == 'POST': # create a form instance and populate it with data from the request: form = NameForm(request.POST) # check whether it's valid: if form.is_valid(): # process the data in form.cleaned_data as required # ... # redirect to a new URL: return HttpResponseRedirect('/thanks/') # if a GET (or any other method) we'll create a blank form else: form = NameForm() return render(request, 'name.html', {'form': form})
所有有用信息都在代码的注释中
-
模板
<form action="/your-name/" method="post"> {% csrf_token %} {{ form }} <input type="submit" value="Submit" /> </form>
{{ form }}
变量中的表单内容会被自动分离并展示出来
在一些浏览器中,对url
,eamil
,number
等标签的合理性检测比Django更为严格,此时可以不使用Django的URLField
,EmailField
等,而使用例如TextField
代替。
Django的Form classes
-
绑定表单实例v.s.非绑定表单实例
- 一个非绑定表单不和任何数据相关联
- 一个绑定表单包含提交的数据,可以用来告诉用户该数据是否合理(若包含的是不合理数据,其可以通过错误信息来告知用户哪种数据是合理的)
通过表单的
is_bound
数据来告知该表单是否绑定数据
更多的表单类型
# forms.py
from django import forms
class ContactForm(forms.Form):
subject = forms.CharField(max_length=100)
message = forms.CharField(widget=forms.Textarea)
sender = forms.EmailField()
cc_myself = forms.BooleanField(required=False)
widgets
每个表单列都有一个对应的widget class
用来指定HTML的表单中<input>
标签的type
属性
大多数情况下,每个field
都有自己默认的widget
,但我们也可以通过widget
参数来显式地指定需要的type
类型
成功提交的数据会以字典的形式保存在表单对象的cleaned_data
属性中
# views.py
if form.is_valid():
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
sender = form.cleaned_data['sender']
cc_myself = form.cleaned_data['cc_myself']
注意,一些字段需要其它的处理方式;比方上传的文件就位于request.FILES
中
处理模板中的表单
{{ form }}
模板变量将根据定义字段自动生成<label>
和<input>
标签
{{ form.as_p }}
, {{ form.as_table }}
, {{ from.as_ul }}
将会在每个表单列上分别添加<p>
, <tr>
和<li>
标签(不要忘记<table>
和<ul>
标签的使用)
上边ContactForm
通过{{ from.as_p }}
得到的HTML表单:
<p><label for="id_subject">Subject:</label>
<input id="id_subject" type="text" name="subject" maxlength="100" required /></p>
<p><label for="id_message">Message:</label>
<textarea name="message" id="id_message" required></textarea></p>
<p><label for="id_sender">Sender:</label>
<input type="email" name="sender" id="id_sender" required /></p>
<p><label for="id_cc_myself">Cc myself:</label>
<input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
注意Django会自动生成label
和id
-
通过字段手动生成表单
{{ form.non_field_errors }} <div class="fieldWrapper"> {{ form.subject.errors }} <label for="{{ form.subject.id_for_label }}">Email subject:</label> {{ form.subject }} </div> <div class="fieldWrapper"> {{ form.message.errors }} <label for="{{ form.message.id_for_label }}">Your message:</label> {{ form.message }} </div> <div class="fieldWrapper"> {{ form.sender.errors }} <label for="{{ form.sender.id_for_label }}">Your email address:</label> {{ form.sender }} </div> <div class="fieldWrapper"> {{ form.cc_myself.errors }} <label for="{{ form.cc_myself.id_for_label }}">CC yourself?</label> {{ form.cc_myself }} </div>
{{ form.non_field_errors }}
标签变量将显示任何非字段错误的信息
<label>
标签也可以通过使用label_tag()
方法实现<div class="fieldWrapper"> {{ form.subject.errors }} {{ form.subject.label_tag }} {{ form.subject }} </div>
{{ form.name_of_field.errors }}
将以列表的形式展示出现的错误,并指定一个CSS类errorlist
<ul class="errorlist"> <li>Sender is required.</li> </ul>
根据需要也可以遍历错误
-
遍历表单的字段
使用{% for %}
循环来遍历表单中的字段{% 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 %}
一些
field
的属性:-
{{ field.label }}
:字段的标签(但不包含<label>
这一HTML标签) -
{{ field.label_tag }}
:将字段的标签包裹在<label>
标签中 -
{{ field.id_for_label }}
:字段的id
{{ field.value }}
{{ field.html_name }}
{{ field.help_text }}
{{ field.errors }}
-
{{ field.is_hidden }}
:布尔型 - `{{ field.field }}
注意上述的属性也适用于前一个手动生成表单的方法
-
-
遍历隐藏字段和可见字段
{# 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 %}