[Django] Djaong(八) 表单操作——Form类

概述

在HTML页面中,form表单是通过<form></form>标签来定义的,可以将数据提交给服务器,如:

<form action="demo/hello" method="get">
  First name: <input type="text" name="fname"><br>
  Last name: <input type="text" name="lname"><br>
  <input type="submit" value="提交">
</form>

<form>标签中可以包含许多的表单元素,<input>元素是form表单中最重要的元素,该元素有很多形态,可以根据type指定:

<input type="text" name="name" value="zhangsan"></input>
<input type="radio" name="sex" value="male"></input>
<input type="password" name="password"></input>
<input type="submit" value="Submit">

<form>标签的action属性定义了在提交表单时执行的动作,如果不指定默认当前页面;
<form>标签的method属性定义在提交表单时使用的HTTP请求方法,如果不指定默认GET方法。

Django中的表单处理

处理表单数据是一个复杂的过程,要对数据进行校验、显示等等,因此Django中提供了Form类来描述一个form表单并决定如何工作和显示,大大简化了这些操作。
Form和<form>的关系跟Model和数据库的关系类似。Model会将定义的字段映射到数据库中,而Form则会将定义的字段映射到<input>表单元素中。此外还提供了ModelForm类用于将Model中的字段通过Form映射到<input>元素中。
在向view中渲染一个Model时,流程一般为:

  • 1.在视图中从数据库获取要显示的数据
  • 2.将它传递给模板上下文
  • 3.使用模板变量将其扩展为HTML标记

渲染Form也类似,不过区别在于,如果一个Model中没有包含数据时,在渲染时模板中为空即可,但是如果一个form表单中数据为空时,也对其进行渲染,以提示用户,这是更加友好的一种方式。
在处理Model实例时,会从View中获取它,当处理form时,会在View中实例化它。
下面是Django中操作表单的最基本使用示例:

  • step1.首先定义一个Form类,并定义Form类字段,以创建对应表单中的表单元素:
# forms.py

from django import forms

class NameForm(forms.Form):
    # 相当于<input type="text">
    name = forms.CharField(label="your name", max_length=40)
  • step2.定义一个View,在View中获取Form实例,并传给模板文件:
from django.shortcuts import render
from .forms import NameForm
from django.http import HttpResponse


def get_name(request):

    if request.method == 'POST':
        form = NameForm()
        if form.is_valid():
            return HttpResponse('/thanks/')
    else:
        form = NameForm()
    return render(request, 'formdemo/name.html', {'form': form})
  • step3.定义模板,用来显示View中要进行渲染的Form:
<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit" />
</form>

完成以上三步后,在浏览器中访问get_name视图的url,一个form表单则会显示出来。
在获取Form实例时,如果是GET请求,则会创建一个空的Form实例,传递给模板上下文;如果是POST请求,则会创建一个Form实例,并且将request中的数据填充给它,这个过程称为“绑定表单”。
Form中提供了is_valid()方法,用于判断提交给Form实例的数据是否有效。如果该方法返回值为Flase,则会将Form中的数据重新带回到模板文件中,填充给HTML中的form表单,并根据需要进行编辑和改正。如果返回True,则form中所有验证的数据都会包含在cleaned_data属性中,在重定向之前,可以利用该属性将数据保存到数据库或者做其他处理。

Form对应的模板

如上例所实现一样,在模板文件中,不需要太多的工作,所有form中的数据和属性都会从DTL的{{ form }}中解析为HTML形式的<form>中。
{% csrf_token %}是CSRF标记,Cross Site Request Forgeries. 使用该标记可以防止CRSF。
结合以上总结,要使用一个表单,应该由Django的Form类进行描述定义,由View生成该Form实例进行处理,并呈现为HTML的<form>

Form常用属性和方法

cleaned_data:包含所有提交到form的有效数据的字典。
is_valid():判断提交到Form中的数据是否有效;
is_bound():判断Form是否进行了绑定;

ModelForm

如果通过表单来对Django的Model直接进行处理,比如将提交的数据实例化为一个Model实例并添加、编辑等,可以使用ModelForm

绑定表单和非绑定表单

  • 非绑定表单:没有数据关联,呈现给用户的将是空的或是默认值;
  • 绑定表单中包含提交的数据,因此可以用来校验数据,如果绑定了无效的数据,则会包含一些内联错误告诉用户要更正哪些数据。
  • is_bound属性可以判断Form是否绑定。

Field类

在定义Form时,必须定义表单的字段——FormField,来指定要提交的数据类型,每个表单字段都有一个相应的Widget类,它又对应于一个HTML表单控件。可以在定义字段时使用widget=来指定Widget。常用的FormField及其对应的Widget和HTML如下表所示:

Field 对应Widget 对应HTML元素
CharField TextInput <input text="text">
DateTimeField TextInput <input type="text">
ChoiceField Select <select><option ...>...</select>
FileField ClearableFileInput <input type="file" ...>
DateField DateInput <input type="file" ...>

Field常用属性

required:默认情况下,每个字段的值都是必须的,因此当传入空值,如None或者''时,clean()方法会引发一个ValidationError异常,因此如果在定义字段时指定required=False,则可以允许为空,如:

name = forms.CharField(required=False)

label:指定该字段对用户来说更加友好;

Widget类

Widget是Django中对HTML<input>元素的表示方式,每个Field字段都有一个Widget相对应,负责处理HTML的渲染以及从与该Widget对应的GET / POST字典中提取数据。

指定一个Widget

为一个Field指定一个Widget,可以通过widget属性进行:

description = forms.CharField(widget="textarea")

猜你喜欢

转载自blog.csdn.net/fightfightfight/article/details/80138720