【Django 笔记】表单

笔记主要基于官方文档,从中提取要点和记录笔记,关键处包含了官方文档链接。详见官方文档。

官方文档:Django documentation 

博客推荐:Django2.2教程

目录

1.HTML表单

2.Django 中的表单

实例化、处理和渲染表单

3.使用Django的表单

3.1.编写Form 类

3.2.视图处理

3.3.模板处理

4.详解 Form 类

4.1.字段详解

4.2.Widget控件

4.3.字段数据

5.使用表单模板


Django 提供了一个丰富的框架来帮助创建表单和处理表单数据。

表单官方文档表单;基础部分文档: 概览 | 表单 API | 内建字段 | 内建 widgets

1.HTML表单

在HTML中,表单 <form>...</form> 可以收集其内部标签中的用户输入,然后将数据发送到服务端。

一个HTML表单必须指定两样东西:

  • 目的地:用户数据发送的目的URL
  • 方式:发送数据所使用的HTTP方法

以Django Admin站点登录表单的HTML为例:

<form action="/admin/login/?next=/admin/" method="post" id="login-form">

    <input type='hidden' name='csrfmiddlewaretoken' 
         value='NNHZaDVJGduajNMECXygKZkAt8vyEcw9HS2qm2Vdf7brDZrA0qK1R0I7M2p3TKcs' />

    <div class="form-row">
        <label class="required" for="id_username">用户名:</label> 
        <input type="text" name="username" autofocus maxlength="254" required id="id_username" />
    </div>

    <div class="form-row">
        <label class="required" for="id_password">密码:</label> 
        <input type="password" name="password" required id="id_password" />
        <input type="hidden" name="next" value="/admin/" />
    </div>

    <div class="submit-row">
        <label>&nbsp;</label> <input type="submit" value="Log in" />
    </div>
</form>
  • 表单数据 <form> 的 action 属性指定URL,告诉浏览器表单应该发往哪里;
  • method 属性指定HTTP方法——如 post ;(GET 和 POST
  • 表单包含了一些 <input> 元素type="text"用于用户名,type="password"用于密码,type="submit"用于“登录"按钮。
  • 当点击<input type="submit" value="Log in">元素时,数据将发送给指定URL。

通常情况下,我们需要自己手动在HTML页面中,编写form标签和其内的其它元素。但这比较麻烦,Django的表单功能可以简化和自动化上述工作的大部分内容

2.Django 中的表单

Django表单会处理涉及的三个不同部分:

  • 准备并重组数据,以便下一步的渲染
  • 为数据创建HTML 表单
  • 接收并处理客户端提交的表单及数据

您 可以 手动编写代码来实现,但Django 可以帮你完成所有这些工作。

编写Django的form表单,非常类似我们在模型系统里编写一个模型。在模型中,一个字段代表数据表的一列,而form表单中的一个字段代表<form>中的一个<input>元素。Django表单系统的核心组件是 Form 类。

实例化、处理和渲染表单

在Django中渲染一个对象的时候,我们通常:

  1. 在视图中获取它(例如从数据库中取出)
  2. 将它传递给模板上下文
  3. 使用模板变量将它扩展为HTML标记

在模板中渲染表单几乎与渲染任何其他类型的对象的一样,但是也存在一些关键性的差异。

3.使用Django的表单

通常三个步骤:

  1. 编写表单类
  2. 视图处理
  3. 模板处理

假设希望在网站上创建一张简易的表单,用来获取用户的名字。需要在模板中使用类似代码:

<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表单可完成以上大部分工作。

3.1.编写Form 类

通过Django提供的Form类可以自动生成上面的表单,不再需要手动在HTML中编写。

在当前app内新建一个forms.py文件(就像views.pymodels.py等):

# forms.py
from django import forms

class NameForm(forms.Form):
    your_name = forms.CharField(label='Your name', max_length=100)

首先它在HTML的 <input> 上增加了 maxlength="100" (这样浏览器会在第一时间阻止用户输入超过这个数量的字符串)。其次它还会在Django收到浏览器传过来的表单时,对数据长度进行验证(也就是服务器端验证)。

注意:

  • 提前导入forms模块
  • 所有的表单类都要继承forms.Form类
  • 每个表单字段都有自己的字段类型比如CharField,它们分别对应一种HTML语言中的<form>元素中的表单元素。这一点和Django模型系统的设计非常相似。
  • 例子中的label用于设置说明标签
  • max_length限制最大长度为100。它同时起到两个作用,一是在浏览器页面限制用户输入不可超过100个字符,二是在后端服务器验证用户输入的长度不可超过100。
  • 每个Django表单的实例都有一个内置的 is_valid() 方法,用来验证接收的数据是否合法。如果所有数据都合法,那么该方法将返回True,并将所有的表单数据转存到它的一个叫做cleaned_data的属性中,该属性是以个字典类型数据。

将上面的表单渲染成真正的HTML元素,其内容如下:

<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100" required />

注意,它不包含<form>标签本身以及提交按钮!为什么要这样?方便你自己控制表单动作和CSS,JS以及其它类似bootstrap框架的嵌入!

3.2.视图处理

表单数据由视图来处理,一般和发布这个表单用的是同一个视图,以重用一些相同的逻辑。

为了处理表单,需要将它实例化到我们希望发布的URL的对应的视图中:

# views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect

from .forms import NameForm

def get_name(request):
    # 如果form通过POST方法发送数据
    if request.method == 'POST':
        # 接受request.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})
  • 对于GET方法请求页面时,创建一个空的表单实例并将其放置在模板上下文中进行渲染,返回空的表单,让用户可以填入数据;
  • 对于POST方法,接收表单数据,并验证;
  • 如果数据合法,按照正常业务逻辑继续执行下去;
  • 如果不合法,返回一个包含先前数据的表单给前端页面,方便用户修改

详见官方文档。

3.3.模板处理

Django的模板中,我们只需要按下面处理,就可以得到完整的HTML页面:

<form action="/your-name/" method="post">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>

所有的表单字段及其属性都将通过Django模板语言从 {{ form }} 中被解包成HTML标记。

注意:

  • <form>...</form>标签要自己写;
  • 使用POST的方法时,必须添加{% csrf_token %}标签,用于处理csrf安全机制;
  • {{ form }}代表Django为你生成其它所有的form标签元素,也就是我们上面做的事情;
  • 提交按钮需要手动添加!

以上是入门需要了解的内容。

4.详解 Form 类

模型和表单

实际上,如果您的表单是要直接用来添加或编辑Django模型,用 ModelForm ,可以省时、省力、省代码,因为它会根据 Model 类构建一张对应字段及其属性的表单。参考:从模型创建表单

了解:绑定的和未绑定的表单实例

4.1.字段详解

实际上,Django的表单模块为我们内置了许多表单字段。

见下面表单:

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)

这个例子中,我们的表单有四个字段: subject 、 message 、 sender 和 cc_myself 。用到三种可用的字段类型: CharField 、 EmailField 和 BooleanField ;

完整的字段类型清单请参看 Form fields 。

4.2.Widget控件

每个表单字段都有一个相对应的 控件类 ,这个控件类又有对应的HTML表单的一种input元素类型,比如 <input type="text"> 。需要在HTML中实际使用什么类型的input,就需要在Django的表单字段中选择相应的field。比如要一个<input type="text">,可以选择一个CharField

4.3.字段数据

无论用表单提交了什么数据,一旦通过调用 is_valid() 验证成功( is_valid() 返回 True ),已验证的表单数据将被放到 form.cleaned_data 字典中。就可以从form.cleaned_data字典中读取所有的表单数据。

在视图中处理表单数据的例子:

# views.py
from django.core.mail import send_mail

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']

    recipients = ['[email protected]']
    if cc_myself:
        recipients.append(sender)

    send_mail(subject, message, sender, recipients)
    return HttpResponseRedirect('/thanks/')

5.使用表单模板

只需将表单实例放到模板的上下文中即可。因此,如果表单在上下文中叫 form ,那么 {{ form }} 将渲染它相应的 <label> 和 <input> 元素。

表单渲染格式

{{ form }}模板语言,能简单地将表单渲染到HTML页面中。对于 <label> / <input> 对,还有其他输出选项:

  • {{ form.as_table }} 将表单渲染成一个表格元素,每个输入框作为一个<tr>标签
  • {{ form.as_p }} 将表单的每个输入框包裹在一个<p>标签内 
  • {{ form.as_ul }} 将表单渲染成一个列表元素,每个输入框作为一个<li>标签

注意:

  • 必须自己提供外层的 <table> 或 <ul> 元素。
  • 一张表单的输出  包含外层 <form> 标签以及 submit 控件。这些必须由你自己提供。

实例和更多信息见官方文档:表单渲染格式

手动渲染字段

直接{{ form }}虽然好,但是往往还达不到要求,比如要使用CSS和JS,要引入Bootstarps框架,这都需要对表单内的input元素进行额外控制。

可以通过{{ form.name_of_field }}获取每一个字段,然后分别渲染;

label标签甚至可以用label_tag()方法来生成;

详见官方文档。

以上仅为基础内容,更多详见官方文档。表单官方文档表单: 概览 | 表单 API | 内建字段 | 内建 widgets

-----end-----

发布了50 篇原创文章 · 获赞 10 · 访问量 6586

猜你喜欢

转载自blog.csdn.net/qq_23996069/article/details/104966311