https://docs.djangoproject.com/en/2.1/ref/forms/
https://docs.djangoproject.com/en/2.1/topics/forms/
更多Form细节内容,见:https://docs.djangoproject.com/en/2.1/ref/forms/
文章目录
1.简介
在html中,form就是位于一对<form>
,</form>
标签里面元素的集合,这些元素用于给用户提供接口,使得用户可以输入文本、单选、元素控制等操作。
在form中,主要用于声明两件事:
- 数据提交的URL;
- 数据提交的方法。
GET和POST是唯一两个用于处理表单的Http方法。对于post方法中,浏览器将表单中的数据打包,编码,然后发送给server,然后从server中获取response。对于GET 方法,直接将数据转成一个字符串,然后编码到URL中。
1.1 在表单处理中,Django 的角色
处理表单是一个非常复杂的工作。以Django admin为例,表单处理涉及到如下几个方面:如何将大量的、不同类型的、展示在表单中、如何处理表单数据的渲染(渲染成html)、如何给用户提供简单的编辑输入接口、如何将用户输入的数据传递给服务器、还需要处理数据的清洗和校验、保存保存工作。
Django 的表单功能涉及到了上述的大部分功能,并将上述功能归为三个部分:
- 数据准备与重构,使得方便进行渲染;
- 为数据生成html网页;
- 接受然后处理client传输过来的数据;
当然你也可以全部自己编写上述代码,但是Django已经有了上述的解决方法,你可以直接使用。
1.2 实例化、处理、渲染表单
当处理表单时,通常会是实例化对应的Django Form对象。当实例化一个表单时,可以将内容置空,或是填上一些预定义的值,例如:
- 使用某个保存的model 实例数据;
- 或是从其他来源获取的值;
- 或是从之前提交的html表单中的数据;
上述功能可支持用户浏览数据,同时也可以会送数据给server。
2.如何构建表单
假设你需要创建一个简单的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>
上述代码告诉你的浏览器:将数据返回给/your-name/
,并使用post方法提交数据。数据展示时,显示一个文本,标签为:“Your name:",另外,显示一个按钮,按钮上的文字为“OK”。如果你的模版中包含了 current_name 变量,则会提前填充好your_name
域。
你需要一个view 来渲染这个html模版,并填入current_name
值。
当表单提交时,发送的Post请求会包含form中的数据。
然后,你需要一个view来响应这个URL,它可以获取到用户输入的key/value对。
这是一个简单的例子,在实际场景下,你可能需要提交大量的数据,且这些数据需要校验,可能在用户提交处理前,在浏览器上就提出用户校验错误提示。这个时候,你就需要用到Django form。
2.1 Django中的表单Form类
Django中表单的核心是Form类。Form类决定类一个表单的样子,包含的元素,也决定类一个表单如何工作,如何展示。
正如一个model中的字段可以和数据库表中的域建立映射关系,Form类中的成员也可以和html中的input元素建立映射关系。(对于ModelForm来说,可以直接建立一个model 字段和html form中的input元素建立映射。
form的成员本身也是类,他们负责管理form中的数据,当form提交时,也可以进行数据校验。例如DateFiled,FileFiled就是用于管理日期、文件的类。在浏览器中端,对于用户而言,一个Form的成员就是一个html widget,一种用户接口机制。每种Form filed对会对应一个默认的Widget 类,但是这个默认的对应关系可以修改。
2.2 在Django中构建form
在决定了在html中的form的样式后,在Django中,构建Django Form就对应为:
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
上述代码定义了一个Form类,该类定义类一个域(your_name)。在域上添加label,用于信息标签展示。对于max_length的作用是:在浏览器端,可以防止用户输入多余100 位的数据;另外,当server收到请求后,可以检验数据是否非法。
Form实例包含is_valid方法,用于数据校验。当所有的域都返回true时,则该方法返回true,然后将form数据放到 cleaned_data属性中。
该form在初始渲染时,展示的样式如下:
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100" required>
注意:渲染结果不包含<form>
标签,也不包含提价按钮。我们需要在模版中自己定义。
form中的数据会传递给view。一般来说,处理该form提交的view和返回生成该form的view是同一个。为了处理form数据,需要实例化对应的Form实例。
from django.http import HttpResponseRedirect
from django.shortcuts import render
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})
2.3 template:内容模版
对于内容模版,我们没有太多的工作。例如,对于上例中的name.html模版,内容如下:
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
2.4. Django form中其他事项
所有的form类都应该是django.forms.Form
或django.forms.ModelForm
的子类
(实际上,ModelForm也是Form的子类)。Form. Form 和 ModelForm从BaseForm中继承了一些通用的功能。
Form中一个Filed就是一个数据元素,每个数据元素都有一个类型,如 CharField, EmailField , BooleanField 等。特定的XXFiled类型对应特定的某种Widget。当Form中的数据校验通过后,就会放入到form的cleaned_data 字典中。该字典中的数据已经转化成对应的Python类型了。当然,你也可以通过Request.POST 直接获取没有经过校验的数据,但是访问经过校验的数据更好。
4. Django 模版
对于Django 模版的化,个人感觉如果你是全栈工程师,且你需要使用Django 这一套来做展示,那么你需要知道。否则的化,你直接返回数据,将数据展示工作交给前端就好了。