Django 表单系统的核心部分是 Form 类,Form 类描述一个表单并决定它如何工作和展现。类似于模型类的属性映射到数据库的字段,表单类的字段会映射到 HTML 表单的 <input> 元素或其他元素。
Django 会处理涉及表单的三个不同部分:
- 准备并重组数据,以便下一步的渲染
- 为数据创建 HTML 表单
- 接收并处理客户端提交的表单及数据
所有表单类都作为 django.forms.Form 的子类来创建,包括 ModelForm 。表单主要分两种:基于 django.forms.Form 和基于 django.forms.ModelForm 。
ModelForm 会根据 Model 类构建一个对应字段及其属性的表单。
构建表单
1. 在 form.py 中定义一个 Form 类:
1 from django import forms
2
3 class NameForm(forms.Form):
4 username = forms.CharField(label='用户名', max_length=100)
- 我们为 username 字段提供了标签,当它渲染后会显示在 <lable> 中。
- 定义了字段的最大长度 max_length,会对浏览器传过来的表单数据长度进行验证。
整个表单在第一次渲染时,会显示如下:
<label for="id_username">用户名:</label>
<input type="text" name="username" maxlength="30" id="id_username" required>
注意:模板没有包含 <form> 标签和 submit 控件。我们必须自己在模板中提供。
2. 在 views.py 视图中实例化表单和处理表单数据
1 from django.shortcuts import render, redirect
2 from .forms import NameForm
3
4 def get_name(request):
5 if request.method == 'POST':
6 form = NameForm(request.POST)
7 if form.is_valid():
8 ...
9 return redirect('/PATH/')
10 else:
11 form = NameForm()
12 return render(request, 'name.html', {'form': form})
如果表单提交用的是 POST 请求,视图将创建一个表单实例并使用请求中的数据填充它。
表单实例有一个 is_valid() 方法,它为表单所有字段进行验证。如果所有字段都包含有效数据,它将返回 True,通过验证的表单数据放到它的属性 cleaned_data 中。
3. 在 html 模板文件中使用表单
<form action="{% url 'app:path' %}" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
所有的表单字段及其属性都将通过 Django 模板语言从 {{ form }} 中被解包成HTML标记。{{ form }} 将渲染它相应的 <lable> 和 <input> 元素。
控件 widget
通常情况下,每个表单字段都有一个相对应的控件,控件又有对应的 HTML 表单控件。例如,CharField 默认具有一个 TextInput 控件,它在 HTML 中生成一个 <input type="text">。
控件负责渲染 HTML 和提取 GET/POST 字典中的数据。
控件默认没有 CSS 类渲染。我们可以通过 widget.attrs 选项对控件进行 CSS 渲染。
username = forms.CharField(label='用户名', max_length=100, widget=forms.TextInput(attrs={'class':'special'}))
表单渲染选项
对于 <lable>/<input>,还有其他输出选项:
- {{ form.as_table }} 封装在 <tr> 标签中
- {{ form.as_p }} 封装在 <p> 标签中
- {{ form.as_ul }} 封装在 <ul> 标签中
注意:我们必须自己提供外层的 <table> 或 <ul> 元素。
我们将 NameForm 实例用 {{ form.as_p }} 输出:
<p>
<label for="id_username">用户名:</label>
<input type="text" name="username" maxlength="30" required id="id_username">
</p>
模型表单
1 from django import forms
2 from django.contrib.auth.models import User
3
4 class UserForm(forms.ModelForm):
5 class Mate:
6 model = User
7 fields = ['username','password']