== 表单(Forms) ==
表单API:https://docs.djangoproject.com/en/1.8/ref/forms/api/
表单属性: https://docs.djangoproject.com/en/1.8/ref/forms/fields/
表单校验: https://docs.djangoproject.com/en/1.8/ref/forms/validation/
-- HTML forms
一个表单除了<input>元素外,还必须指定URL和HTTP方法。
<form action="/admin/" method="POST" >
<input type="text"></input>
<input type="password"></input>
<input type="submit"></input>
</form>
# 在form中仅用到GET和POST这两个HTTP方法。
POST 浏览器绑定form中的数据、编码、发送到服务端,然后接收回应。
GET 将数据绑定到一个字符串,并组成URL的一部分,以key和value形式发送。
不同用途:
POST 用于改变系统状态的请求;
GET 用于不会影响系统状态的请求;如果Search表单;
GET 不适合密码表单,因为会在url中显示;不适合于数据较大的请求。
-- Django在表单中的角色
Django处理关于表单(forms)的三部分独立的工作:
* 准备并组织数据用于渲染显示
* 为数据创建HTML表单
* 接收并处理来自客户端提交的表单和数据
可以手动写代码来处理这些工作,但Django能帮你全部处理这些。
-- Django中的Forms
# Django的Form类
核心组件,Form类定义了一个表单,并决定它如何工作和展示。
Form类的属性映射为HTML表单的<input>元素 (ModelForm通过Form将model类属性映射到HTML<input>元素)。
Form的属性字段本身也是类,它们管理form数据并在form提交时进行校验。
一个Form字段在浏览器中以一个HTML"widget"展示。每种字段类型都有不同的默认Widget类。
# 实例化、处理和显示表单
在Django中显示一个对象:
1. 在view中获取对象
2. 将对象传递给Template的Context
3. 使用Template参数将其解析为HTML标记
显示一个Form与显示任何其他对象的工作中几乎相同,但有几个关键的不同。
对于没有数据的model对象,在模板中没有什么用。而未预填数据的form,正符合我们想要用户填写的需要。
在view中实例化model实例,通常从数据库获取。而form通常在view中初始化。
当我们实例化一个form时,可以保持它为空对象,或预填写数据:
* 保存的model实例数据
* 从其他来源的数据
* 前一个form提交的数据
-- 创建一个表单
# 所需工作
<form action="/your-name/" method="post">
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
-- 在django中创建表单
----
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
渲染结果
-----
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100">
# 视图(view)
发送到Django后台的form数据由view来处理,通常是发布form的View.
view.py
----
from .forms import NameForm
def get_name(request):
# 如果是POST请求,我们需要处理表单数据
if request.method == 'POST':
# 创建form实例,并使用请求中的数据初始化
form = NameForm(request.POST)
# 检查是否合法
if form.is_valid():
# 处理form.cleaned_data中的数据
# ...
# 重定向到新的URL
return HttpResponseRedirect('/thanks/')
# 如是GET或其他方法,我们将创建一个空表单实例
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
# 模板(template)
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
-- 关于Form类的更多内容
所有form类都被创建为django.forms.Form的子类。
# 绑定和未绑定表单对象
* 未绑定数据表单,显示时为空或默认值。
* 绑定了提交的(submitted)数据的表单,能告知数据是否有效。
可通过is_bound属性区分
# 关于属性
https://docs.djangoproject.com/en/1.8/ref/forms/fields/
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
https://docs.djangoproject.com/en/1.8/ref/forms/widgets/
# 属性值
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']
* Sending email.
https://docs.djangoproject.com/en/1.8/topics/email/
* 绑定上传文件
https://docs.djangoproject.com/en/1.8/ref/forms/api/#binding-uploaded-files
-- 使用表单模板(templates)
你需要做的就是把form对象放到模板的context中({'form': form}),{{form}}将适当的显示<label>和<input>对。
# 显示选项
{{form}}
{{ form.as_table }}
{{ form.as_p }}
{{ form.as_ul }}
# 手动显示字段
每个属性可以通过{{form.name_of_field}}形式获取。
例如:
{{ 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>
# 显示表单错误信息
使用 {{ form.name_of_field.errors }} 显示form的错误列表:
<ul class="errorlist">
<li>Sender is required.</li>
</ul>
或自定义显示:
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
{{ form.non_field_errors }} 用于显示与特定字段无关的错误:
<ul class="errorlist nonfield">
<li>Generic validation error</li>
</ul>
# 循环遍历表单属性
{% 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.label_tag }} => <label for="id_email">Email address:</label> # with label_suffix: defaults to a colon (:) in English
{{ field.id_for_label }} => id_email
{{ field.value }} => someone@example.com
{{ field.html_name }}
{{ field.help_text }}
{{ field.errors }}
{{ field.is_hidden }}
{{ field.field }}
# 隐藏和显示字段
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
# 重用form模板
{% include "form_snippet.html" %}
{% include "form_snippet.html" with form=comment_form %}
---- form_snippet.html: ----
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
表单API:https://docs.djangoproject.com/en/1.8/ref/forms/api/
表单属性: https://docs.djangoproject.com/en/1.8/ref/forms/fields/
表单校验: https://docs.djangoproject.com/en/1.8/ref/forms/validation/
-- HTML forms
一个表单除了<input>元素外,还必须指定URL和HTTP方法。
<form action="/admin/" method="POST" >
<input type="text"></input>
<input type="password"></input>
<input type="submit"></input>
</form>
# 在form中仅用到GET和POST这两个HTTP方法。
POST 浏览器绑定form中的数据、编码、发送到服务端,然后接收回应。
GET 将数据绑定到一个字符串,并组成URL的一部分,以key和value形式发送。
不同用途:
POST 用于改变系统状态的请求;
GET 用于不会影响系统状态的请求;如果Search表单;
GET 不适合密码表单,因为会在url中显示;不适合于数据较大的请求。
-- Django在表单中的角色
Django处理关于表单(forms)的三部分独立的工作:
* 准备并组织数据用于渲染显示
* 为数据创建HTML表单
* 接收并处理来自客户端提交的表单和数据
可以手动写代码来处理这些工作,但Django能帮你全部处理这些。
-- Django中的Forms
# Django的Form类
核心组件,Form类定义了一个表单,并决定它如何工作和展示。
Form类的属性映射为HTML表单的<input>元素 (ModelForm通过Form将model类属性映射到HTML<input>元素)。
Form的属性字段本身也是类,它们管理form数据并在form提交时进行校验。
一个Form字段在浏览器中以一个HTML"widget"展示。每种字段类型都有不同的默认Widget类。
# 实例化、处理和显示表单
在Django中显示一个对象:
1. 在view中获取对象
2. 将对象传递给Template的Context
3. 使用Template参数将其解析为HTML标记
显示一个Form与显示任何其他对象的工作中几乎相同,但有几个关键的不同。
对于没有数据的model对象,在模板中没有什么用。而未预填数据的form,正符合我们想要用户填写的需要。
在view中实例化model实例,通常从数据库获取。而form通常在view中初始化。
当我们实例化一个form时,可以保持它为空对象,或预填写数据:
* 保存的model实例数据
* 从其他来源的数据
* 前一个form提交的数据
-- 创建一个表单
# 所需工作
<form action="/your-name/" method="post">
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
-- 在django中创建表单
# Form类
forms.py----
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
渲染结果
-----
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100">
# 视图(view)
发送到Django后台的form数据由view来处理,通常是发布form的View.
view.py
----
from .forms import NameForm
def get_name(request):
# 如果是POST请求,我们需要处理表单数据
if request.method == 'POST':
# 创建form实例,并使用请求中的数据初始化
form = NameForm(request.POST)
# 检查是否合法
if form.is_valid():
# 处理form.cleaned_data中的数据
# ...
# 重定向到新的URL
return HttpResponseRedirect('/thanks/')
# 如是GET或其他方法,我们将创建一个空表单实例
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
# 模板(template)
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
-- 关于Form类的更多内容
所有form类都被创建为django.forms.Form的子类。
# 绑定和未绑定表单对象
* 未绑定数据表单,显示时为空或默认值。
* 绑定了提交的(submitted)数据的表单,能告知数据是否有效。
可通过is_bound属性区分
# 关于属性
https://docs.djangoproject.com/en/1.8/ref/forms/fields/
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
https://docs.djangoproject.com/en/1.8/ref/forms/widgets/
# 属性值
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']
* Sending email.
https://docs.djangoproject.com/en/1.8/topics/email/
* 绑定上传文件
https://docs.djangoproject.com/en/1.8/ref/forms/api/#binding-uploaded-files
-- 使用表单模板(templates)
你需要做的就是把form对象放到模板的context中({'form': form}),{{form}}将适当的显示<label>和<input>对。
# 显示选项
{{form}}
{{ form.as_table }}
{{ form.as_p }}
{{ form.as_ul }}
# 手动显示字段
每个属性可以通过{{form.name_of_field}}形式获取。
例如:
{{ 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>
# 显示表单错误信息
使用 {{ form.name_of_field.errors }} 显示form的错误列表:
<ul class="errorlist">
<li>Sender is required.</li>
</ul>
或自定义显示:
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
{{ form.non_field_errors }} 用于显示与特定字段无关的错误:
<ul class="errorlist nonfield">
<li>Generic validation error</li>
</ul>
# 循环遍历表单属性
{% 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 }} => Email address{{ field.label_tag }} => <label for="id_email">Email address:</label> # with label_suffix: defaults to a colon (:) in English
{{ field.id_for_label }} => id_email
{{ field.value }} => someone@example.com
{{ field.html_name }}
{{ field.help_text }}
{{ field.errors }}
{{ field.is_hidden }}
{{ field.field }}
# 隐藏和显示字段
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
# 重用form模板
{% include "form_snippet.html" %}
{% include "form_snippet.html" with form=comment_form %}
---- form_snippet.html: ----
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}