django中表单处理

在web端与后端交互时,咱们除了使用html原生的form标签,还可使用django自带的表单。html

Django 提供普遍的工具和库来帮助你构建表单来接收网站访问者的输入,而后处理以及响应输入。前端

HTML表单

在HTML中,表单的做用是收集标签中的内容,<form>...</form> 中间能够由访问者添加相似于文本,选择,或者一些控制模块等等.而后这些内容将会被送到服务端web

某些表单的元素 —— 文本输入和复选框 —— 很是简单并且内建于HTML 自己。 其余的复杂得多;弹出日期选择器或容许您移动滑块或操纵控件的界面一般将使用JavaScript和CSS以及HTML表单<input>元素来实现这些效果。数据库

<input> 元素同样,一个表单必须指定两样东西:django

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

GET和POST方法

Django 的登陆表单使用POST 方法,在这个方法中浏览器组合表单数据、对它们进行编码以用于传输、将它们发送到服务器而后接收它的响应。后端

相反,GET 组合提交的数据为一个字符串,而后使用它来生成一个URL。 这个URL 将包含数据发送的地址以及数据的键和值。浏览器

post和get用于不一样的目的:安全

用于改变系统状态的请求 —— 例如,给数据库带来变化的请求 —— 应该使用POSTGET 只应该用于不会影响系统状态的请求。服务器

GET 还不适合密码表单,由于密码将出如今URL 中,以及浏览器的历史和服务器的日志中,并且都是以普通的文本格式。 它还不适合数据量大的表单和二进制数据,例如一张图片。 使用GET 请求做为管理站点的表单具备安全隐患:攻击者很容易模拟表单请求来取得系统的敏感数据。 POST,若是与其它的保护措施结合将对访问提供更多的控制,例如Django 的CSRF protectionapp

另外一个方面,GET 适合网页搜索这样的表单,由于这种表示一个GET 请求的URL 能够很容易地做为书签、分享和从新提交

django中的表单

在一个Web 应用中,"表单"可能指HTML <form>、或者生成它的Django 的Form、或者提交时发送的结构化数据、或者这些部分的总和。

django的FORM类

表单系统的核心部分是Django 的Form 类。 Django 的模型描述一个对象的逻辑结构、行为以及展示给咱们的方式,与此相似,Form 类描述一个表单并决定它如何工做和展示。

就像模型类的属性映射到数据库的字段同样,表单类的字段会映射到HTML 的<input>表单的元素。 ModelForm 经过一个Form 映射模型类的字段到HTML 表单的<input> 元素;Django 的Admin 站点就是基于这个)。

一个表单的字段自己就是类;他们管理表单数据,并在提交表单时执行验证。 DateFieldFileField 处理的数据类型差异很大,必须完成不一样的事情。

表单字段在浏览器中呈现给用户的是一个HTML 的“widget” —— 用户界面的一个片断。 每一个字段类型都有一个合适的默认Widget class,须要时能够覆盖。

构建表单

构建一个表单,获取用户的输入信息便可!

正常使用html写django提交表单以下:

    <form action="/info/" method="post">
        <label for="meg">请输入信息</label>
        <input type="text" id="meg"><br>
        <input type="submit" value="提交">
        {% csrf_token %}
    </form>

随着业务逻辑的应用,咱们可能须要愈来愈多的input标签,而且还须要对标签输入的内容作一些处理等等。所以为了更方便的处理表单提交,django引入了FORM类。

一个简单的表单应用以下:

由于比较简单咱们把Form表单与视图函数写在了一个文件中(不推荐):

# *-* coding:utf-8 *-*
from django.shortcuts import render

# Create your views here.
from django import forms


class InfoForm(forms.Form):
    info = forms.CharField(label=u"用户信息", max_length=100)          #注意这里的类属性定义的info不能省略,否则不会再前端显示


infoform = InfoForm()              #实例化表单数据,而且把表单实例对象传递给html页面


def info(request):
    return render(request, "info.html", {"infoform": infoform})

它定义一个Form 类,只带有一个字段(info)。 咱们已经对这个字段使用一我的性化的标签,当渲染时它将出如今<label> 中(在这个例子中,即便咱们省略它,咱们指定的label仍是会自动生成)。

字段容许的最大长度经过max_length 定义。 它完成两件事情。 首先,它在HTML 的<input> 上放置一个maxlength="100" (这样浏览器将在第一时间阻止用户输入多于这个数目的字符)。 它还意味着当Django 收到浏览器发送过来的表单时,它将验证数据的长度。

Form 的实例具备一个is_valid() 方法,它为全部的字段运行验证的程序当调用这个方法时,若是全部的字段都包含合法的数据,它将:

  • 返回True
  • 将表单的数据放到cleaned_data 属性中。

前端代码以下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/info/" method="post">
        {{ infoform }}
        <input type="submit" value="提交">
        {% csrf_token %}                   #这个是django为了表单的安全验证必须添加,若不想添加能够如今中间件哪里注释掉对应的验证。
    </form>
</body>
</html>

展现效果以下:

 格式须要本身写!

上面咱们把表单的数据提交了,那么在后台改如何处理呢?咱们知道视图层的做用就是做为先后端交互的中间层,那么表单提交的数据天然也是在视图层处理了。

# *-* coding:utf-8 *-*
from django.shortcuts import render, HttpResponse

# Create your views here.
from django import forms


class InfoForm(forms.Form):
    info = forms.CharField(label=u"用户信息 ", max_length=100)


infoform = InfoForm()


def info(request):
    if request.method == "GET":                       #如果GET访问,则是直接访问上面这个表单页面
        return render(request, "info.html", {"infoform": infoform})
    elif request.method == "POST":                    #如果POST访问,而后提取数据,处理数据
        form = InfoForm(request.POST)                 #首先把request.POST对象做为参数传递给InfoForm来实例化,经过表单的方式来处理数据
        if form.is_valid():                           #is_valid()方法上面提到过、
            print "OK"
            print form.cleaned_data                   #打印出表单提交的数据,返回的是一个字典。
            return HttpResponse("<h1>提交成功</h1>")
        else:
            return HttpResponse("error")

打印的结果是一个字典:

{'info': u'i have a dream'}

#这里使用了cleaned_data方法,这个方法返回的是表单提交数据信息(咱们须要的数据),这里仅仅有咱们须要的用户输入的信息。
#固然这里的表单处理,依然可使用以前的request.POST方法来处理。

视图的整个逻辑是这样的:

若是访问视图的是一个GET 请求,它将建立一个空的表单实例并将它放置到要渲染的模板的上下文中。 这是咱们在第一次访问该URL 时预期发生的状况。

若是使用POST请求提交表单,该视图将再次建立一个表单实例,并使用请求中的数据填充表单:形式 = NameForm(request.POST)这被称为“将数据绑定到表单”(如今是绑定的形式)。

咱们调用窗体的is_valid()方法;若是不是True,咱们返回到表单的模板。 这时表单再也不为空(未绑定),因此HTML 表单将用以前提交的数据填充,而后能够根据要求编辑并改正它。

若是True 为is_valid(),咱们将可以在cleaned_data 属性中找到全部合法的表单数据。 在发送HTTP 重定向给浏览器告诉它下一步的去向以前,咱们能够用这个数据来更新数据库或者作其它处理。

上面经过了一个简单的实例说明了django表单的使用流程,django表单的用法仍是很强大的,下面会详细说明其用法。

django的forms类

全部的表单类都做为django.forms.Form 的子类建立,包括你在Django 管理站点中遇到的ModelForm

绑定和未绑定数据的表单:

  • 不包含数据的表单称为未绑定表单。 当render给用户时,它将为空或包含默认的值。
  • 包含数据的表单称为绑定表单,所以能够用来检验数据是否合法。 若是渲染一个不合法的绑定的表单,它将包含内联的错误信息,告诉用户如何纠正数据。

表单的is_bound 属性将告诉你一个表单是否具备绑定的数据。

把上面视图函数中的print “OK”位置换成下面的:

print form.is_bound                   #表单已经绑定则返回True,不然返回False ##结果
{'info': u'i have a dream'}           #这个为print cleanted_data打印的结果
True    

无论表单提交的是什么数据,一旦经过调用is_valid() 成功验证(is_valid() 返回True),验证后的表单数据将位于form.cleaned_data 字典中。 这些数据已经为你转换好为Python 的类型。

表单渲染

上面的实例中,咱们infoform表单被渲染为label标签和input标签,这两个标签须要放入form表单中才可使用。这是表单的默认渲染方式。

咱们还能够有如下的渲染方式:

    {{ form.as_table }} 以表格的形式将它们渲染在<tr> 标签中
    {{ form.as_p }} 将它们渲染在<p> 标签中
    {{ form.as_ul }} 将它们渲染在<li> 标签中


#实例
    <ul>
        {{ infoform.as_ul }}
    </ul>

分解form表单:

上面在前端上面引用时,咱们直接引用了{{ infoform }}的形式,可是这个变量包含了许多数据,有时候咱们为了本身渲染每一个部分,须要单独的提取某个部分,而后处理:

属性     说明
{{ field.label }}     字段对应的label信息
{{ field.label_tag }}     自动生成字段的label标签,注意与{{ field.label }}的区别,它包含表单的例如,默认的 是一个冒号:
{{ field.id_for_label }}     自定义字段标签的id
{{ field.value }}     当前字段的值,好比一个Email字段的值someone@example.com
{{ field.html_name }}     指定字段生成的input标签中name属性的值
{{ field.help_text }}     字段的帮助信息
{{ field.errors }}     包含错误信息的元素
{{ field.is_hidden }}     用于判断当前字段是否为隐藏的字段,若是是,返回True
{{ field.field }}     返回字段的参数列表。例如{{ char_field.field.max_length }}label_suffixlabel_suffix

隐藏字段的处理

若是你正在手工布局模板中的一个表单,而不是依赖Django 默认的表单布局,你可能但愿将<input type="hidden"> 字段与非隐藏的字段区别对待。 例如,由于隐藏的字段不会显示,在该字段旁边放置错误信息可能让你的用户感到困惑 —— 因此这些字段的错误应该有区别地来处理。

Django 提供两个表单方法,它们容许你独立地在隐藏的和可见的字段上迭代:visible_fields()hidden_fields()

 

{# Include the hidden fields #}              #注释信息
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{# Include the visible fields #}             #注释信息
{% for field in form.visible_fields %}       
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

 

这个示例没有处理隐藏字段中的任何错误信息。 一般,隐藏字段中的错误意味着表单被篡改,由于正常的表单填写不会改变它们。 然而,你也能够很容易地为这些表单错误插入一些错误信息显示出来。

 

重用表单渲染

若是你的网站在多个地方对表单使用相同的渲染逻辑,你能够保存表单的循环到一个单独的模板中来减小重复,而后在其它模板中使用include 标签来重用它:

# In your form template:
{% include "form_snippet.html" %}

# In form_snippet.html:
{% for field in form %}
    <div class="fieldWrapper">
        {{ field.errors }}
        {{ field.label_tag }} {{ field }}
    </div>
{% endfor %}

若是传递到模板上下文中的表单对象具备一个不一样的名称,你可使用include 标签的with 参数来对它起个别名:

 {% include "form_snippet.html" with form=comment_form %}

 django表单的字段:https://yiyibooks.cn/xx/Django_1.11.6/ref/forms/fields.html

相关文章
相关标签/搜索