1、HTML中的表单

在HTML种,表单是在<form>...</form>种的元素,它允许用户输入文本,选择选项,操作对象等,然后发送这些数据到服务器

表单元素允许用户在表单种输入内容如,文本域(textarea)、下拉列表、单选框(radio-buttons)、复选框(checkboxes)等。

大多数情况下被用到的表单标签是输入标签(<input>),输入类型是由类型属性(type)定义的,大多数经常被用到的输入类型下面做简单介绍:

(1)文本域(Text Fields)

文本域通过<input type="text">标签来设定,当用户要在表单种输入字母,数字等内容是,就会用到文本域,在大多数浏览器种,文本域的缺省宽度是20个字符:

<form>
姓名:<input type="text" name="username"><br>
</form>

(2)密码字段

密码字段通过标签<input type="password">来定义,密码字段字符不会明文显示,而是以星号或圆点替代:

<form>
姓名:<input type="text" name="username"><br>
密码:<input type="password" name="password">
</form>

(3)单选按钮(Radio Buttons)

<input type="radio">标签定义了表单单选框选项

<form>
姓名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
性别:<input type="radio" name="sex" value="man">男<input type="radio" name="sex" value="weman">女<br> </form>

(4)复选框(Checkboxes)

<input type="checkbox"定义了复选框,用户可以从若干个给定的选择种选择多个

<form>
姓名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
性别:<input type="radio" name="sex" value="man">男<input type="radio" name="sex" value="weman">女<br>
爱好:<input type="checkbox" name="vehicle" value="yundong">运动
<input type="checkbox" name="vehicle" value="youxi">游戏
<input type="checkbox" name="vehicle" value="xuexi">学习 </form>

(5)提交按钮(Submit Button)

<input type="submit">定义了提交按钮,当用户单击确认按钮时,表单的内容就会被传送到动作属性定义的目的文件中

<form action="index.html" method="post">
姓名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
性别:<input type="radio" name="sex" value="man">男<input type="radio" name="sex" value="weman">女<br>
爱好:<input type="checkbox" name="vehicle" value="yundong">运动
<input type="checkbox" name="vehicle" value="youxi">游戏
<input type="checkbox" name="vehicle" value="xuexi">学习<br>
<input type="submit" value="提交">
</form>

浏览器表单中的数据会发往action属性指定的URL,并且使用它的method属性指定的HTTP方法post,当点击submit类型的提交时,会将数据发送到index.html中。

HTML5有许多新的input类型:

color类型选取颜色,date类型日期选择器,datetime-local类型选择一个日期和时间,email类型用于e-mail地址的输入域,month类型允许选择一个月份,number类型用于数值的输入域,rang类型定义一定范围内数字的输入域,显示为滑动条可设置最大值max和最小值min,search类型用于搜索域,tel类型定义电话号码字段,time类型定义一个时间选择,url类型用于URL地址的输入域,week类型允许选择周和年。

处理表单时只会用到GET和POST两种HTTP方法,GET方法会将提交的数据捆绑到URL中,而POST通过加密的方式在后台提交

2、Django中的表单

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

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

Django表单系统的核心组件是Form类,Form类描述一张表单并决定它如何工作并呈现

Form类,类似于模型类的字段映射到数据库字段的方式,表单类的字段会映射到HTML表单的<input>元素,表单字段本身也是类,它们管理表单数据并提交表单执行验证,在浏览器中表单字段以HTML控件的形式展现给我们,在Django中每个字段类型都有与之匹配的控件类,在必要时也可以覆盖

在Django中渲染一个对象的过程通常为:在视图中获取数据,然后将数据传递给模板,使用模板变量将数据扩展到HTML标记,下面我们在Django中构建表单

在app中新建forms.py文件:

from django import forms

#首先它继承Form类,然后通过控件类CharField定义文本域并指定属性
class IndexForm(forms.Form):
username = forms.CharField(label='姓名',max_length=100)

然后在编辑视图并引入表单类:

#views.py

from django.shortcuts import render
from django.http import HttpResponse
from .forms import IndexForm #新建视图函数处理表单,首先判断提交类型为post则通过表单类接收POST请求数据并填充表单类,然后判断数据是否有效并提交到后台,此处做演示只做判断并提示接收成功,
#如果提交类型不为POST则创建空表单通过变量传递给模板
def get_name(request):
if request.method == 'POST':
form = IndexForm(request.POST)
print(form)
if form.is_valid():
return HttpResponse('提交到后台成功!')
else:
form = IndexForm()
return render(request,'index.html',{'form':form})

表单类生成的数据如下:

<tr><th><label for="id_username">姓名:</label></th><td><input type="text" name="username" value="root" maxlength="" required id="id_username"></td></tr>

在模板中只需简单的配置form标签并接收变量,注意表单不包含提交标签需要在模板中自己创建

<form action="{% url 'formtest' %}" method="post">
{% csrf_token %} #此处为跨站请求伪造保护功能django自提供
{{ form }}
<input type="submit" value="提交">
</form>

页面程序效果:

<form action="/" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="e9Je91NyzZFWx83yXQbSiHYYjH3g4tsiz22zAjEAhSfKnNzPjAINCVd1iHZAnC4B">
<label for="id_username">姓名:</label><input type="text" name="username" maxlength="100" required="" id="id_username">
<input type="submit" value="提交">
</form>

在模板中我们只需将表单在上下问中进行渲染,来得到对应的标签元素,如上面的form变量渲染{{ form }}

但在表单渲染选项还可以使用其他渲染方式:

{{ form.as_table }}包装在<tr>标记中的表格单元格显示数据,但必须自己提供外层<table>元素

{{ form.as_p }}包裹在<p>标记中的显示数据

{{ form.as_ul }}包裹在<li>标记中显示数据,但必须自己提供外层<ul>元素

手动渲染字段:

循环遍历每个字段对字段属性手动渲染,如下field.errors输出包含改字段验证的错误信息,field.label_tag为带<label>标签的label值

#遍历表单字段
<form action="{% url 'index' %}" method="post">
{% csrf_token %}
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}<br>
{% endfor %}
<input type="submit" value="提交">
</form> #渲染效果
<form action="/" method="post">
<input type="hidden" name="csrfmiddlewaretoken" value="benu1PCIYH6XKtSxa7cQyR8wwwIYvae7w7GPs7tKGAGLA8oOwRJLS5nzvwEiOjQq">
<label for="id_subject">Subject:</label> <input type="text" name="subject" maxlength="" required="" id="id_subject"><br>
<label for="id_message">Message:</label> <textarea name="message" cols="" rows="" required="" id="id_message"></textarea><br>
<label for="id_sender">Sender:</label> <input type="email" name="sender" required="" id="id_sender"><br>
<label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself"><br>
<input type="submit" value="提交">
</form>

field.label_tag:输出field的label元素,如:<label for="id_subject">Subject:</label>

field:输出field的input,如:<input type="text" name="subject" maxlength="100" required="" id="id_subject">

field.errors:输出field的errors元素,一般在form表单验证出错时显示

field.id_for_label:输出字段的ID值

field.value:输出字段填充的值

field.html_name:输出字段的名称

field.help_text:输出与该字段的帮助文本

field.is_hidden:如果是隐藏字段属性值为True否则为False

3、表单集

Formset表单集是多个表单的集合,Formset在web开发中应用很普遍,它可以让用户在同一个页面提交多张表单,一键添加多个数据

Django针对不同的formset提供了三种方法:formet_factory,modelformset_factory和inlineformset_factory

(1)使用formset_factory

对应继承forms.Form的自定义表单,我们可以使用formset_factory,通过设置extra指定表单数量,max_num指定表单数量最大值

首先创建表单并使用formset_factory方法指定创建表单集并指定表单数量

#forms.py

from django import forms
from django.forms import formset_factory class registerForm(forms.Form):
username = forms.CharField(max_length=120)
age = forms.IntegerField()
pub_date = forms.DateField(required=False) registerFormset = formset_factory(registerForm,extra=3,max_num=5)

在视图views.py里使用formset

#views.py

from django.shortcuts import render,HttpResponse
from .forms import registerFormset def register(request):
if request.method == 'POST':
formset = registerFormset(request.POST,request.FILES)
if formset.is_valid():
return HttpResponse('formset is ok')
else:
formset = registerFormset()
return render(request,'register.html',context={'formset':formset})

最后在模版中应用表单即可

<form action="{% url 'register' %}" method="post">
{{ formset.management_form }}
{% for form in formset %}
{{ form.as_p }}
{% endfor %}
</form>

4、从模型创建表单

首先创建model模型:

from django.db import models
from django.utils import timezone TITLE_CHOICES = (
('MR','Mr.'),
('MRS','Mrs.'),
('MS','Ms.'),
) class Author(models.Model):
name = models.CharField(max_length=100,verbose_name='姓名')
title = models.CharField(max_length=3,choices=TITLE_CHOICES,verbose_name='标题')
birth_date = models.DateField(default=timezone.now,blank=True,null=True,verbose_name="创建时间") def __str__(self):
return self.name

根据模型创建表单文件:

#forms.py
#导入模型表单类
from django.forms import ModelForm
from .models import Author #继承模型表单类创建表单
class AuthorForm(ModelForm):
class Meta:
model = Author #指定model
fields = ['name','title','birth_date'] #指定要显示的字段,全显示可使用"__all__"

在通过模型创建表单时,我们只需继承Django的模型表单类,然后重写它的属性即可,model指定要创建表单的模型,fields指定显示的模型字段,全显示可以用“__all__"代替,还有其他的类属性exclude指定排除的字段,labels指定提示信息,help_texts指定帮助提示信息,widgets指定自定义插件,error_messages自定义错误信息,field_classes自定义字段类,localized_fields本地化时区时间,根据setting中TIME_ZONE设置的不同时区显示时间

from django import forms
from django.forms import ModelForm
from .models import Author class AuthorForm(ModelForm):
class Meta:
model = Author
fields = ['name','title','birth_date']
widgets = {
'title':forms.Textarea(attrs={'cols':80,'rows':20})
} #覆盖重写title字段的类型
labels = {
'name':'作者',
'title':'头衔',
'birth_date':'出生日期',
}
error_messages = {
'name':{
'max_length':'名字长度在15个字符内',
}
}

在django中的模型字段和表单字段的字段类型定义都差不多,比较特殊的是ForeignKey和ManyToManyField模型字段在表单中的字段类型会有所不同:

ForeignKey由django.forms.ModelChoiceField表示,它是一个ChoiceField,其选项是一个模型QuerySet

ManyToManyField由django.forms.ModelMultipleChoiceField表示,它是一个MultipleChoiceField,其选项为一个模型QuerySet

另外,每个生成的表单字段的属性设置如下:

如果模型字段设置了blank=True,那么表单字段的required属性被设置为False,否知为True

表单字段的label设置为模型字段的verbose_name,并且首字母大写

表单字段的help_text设置为模型字段的help_text

如果模型字段设置了choices,那么表单字段的widget会被设置为select,其选项来自模型字段的choices,这些选项通常包含一个默认选中的空选项,如果字段设置了必填,则会强制用户进行选项,如果模型字段设置了blank=False以及一个明确的default值,则表单字段中不会包含空选项

在视图中使用表单:

#views.py

from django.shortcuts import render,HttpResponse
from .forms import AuthorForm
from .models import Author def test(request):
if request.method == 'POST':
author_form = AuthorForm(request.POST)
if author_form.is_valid():
author_form.save(commit=True)
return HttpResponse('提交成功')
else:
author_form = AuthorForm()
obj = Author.objects.all()
return render(request,'test.html',{"author_form":author_form,'obj':obj})

views.py中使用ModelForm的save()方法将表单数据保存到数据库中,参数commit为True时写如数据库,如果为False则创建一个Model对象但不保存到数据库中,如果要更新某个对象可以使用save的instance参数来指定要更新的model对象

在模板中提交并展示数据:

#test.html

<body>
<h2>Author Form:</h2>
<form action="{% url 'test' %}" method="post">
{% csrf_token %}
{{ author_form }}
<input type="submit" value="提交">
</form>
<h2>Author Form output:</h2>
<ul>
{% for i in obj %}
<li>{{ i.id }}:{{ i.name }}:{{ i.title }}:{{ i.birth_date }}</li>
{% endfor %}
</ul>
</body>

表单模板ModelForm中有一个工厂函数可以直接通过Model创建表单modelform_factory(),在不需要很多自定义的情况下是很方便的

from .models import Author
from django import forms
from django.forms.models import modelformset_factory modelform_Author = modelformset_factory(model=Author,fields=('__all__'),widgets={'title':forms.Textarea()})

python3之Django表单(一)的更多相关文章

  1. python 全栈开发,Day111(客户管理之 编辑权限(二),Django表单集合Formset,ORM之limit_choices_to,构造家族结构)

    昨日内容回顾 1. 权限系统的流程? 2. 权限的表有几个? 3. 技术点 中间件 session orm - 去重 - 去空 inclusion_tag filter 有序字典 settings配置 ...

  2. django表单的api

    django表单的api,参考文档:https://yiyibooks.cn/xx/Django_1.11.6/ref/forms/api.html 绑定与未绑定形式: Form要么是绑定的,要么是未 ...

  3. Django表单API详解

    声明:以下的Form.表单等术语都指的的广义的Django表单. Form要么是绑定了数据的,要么是未绑定数据的. 如果是绑定的,那么它能够验证数据,并渲染表单及其数据,然后生成HTML表单.如果未绑 ...

  4. 9:django 表单

    django自带表单系统,这个表单系统不仅可以定义属性名,还可以自己定义验证,更有自己自带的错误提示系统 这节我们仅仅粗略的来看一下django表单系统的入门运用(具体的实在太多东西,主要是我觉得有很 ...

  5. django 表单系统 之 forms.Form

    继承forms.Form实现django表单系统 参考: https://www.cnblogs.com/zongfa/p/7709639.html https://www.cnblogs.com/c ...

  6. 关于创建Django表单Forms继承BaseForm的问题

    在创建Django表单时,因为需要验证用户输入的验证码是否正确,因此需要在session里提取当前验证码的值和POST提交过来的值进行比对,如图: form.py from django import ...

  7. Django 表单处理流程

    Django 的表单处理:视图获取请求,执行所需的任何操作,包括从模型中读取数据,然后生成并返回HTML页面(从模板中),我们传递一个包含要显示的数据的上下文.使事情变得更复杂的是,服务器还需要能够处 ...

  8. 第四章:Django表单 - 2:Django表单API详解

    声明:以下的Form.表单等术语都指的的广义的Django表单. Form要么是绑定了数据的,要么是未绑定数据的. 如果是绑定的,那么它能够验证数据,并渲染表单及其数据,然后生成HTML表单.如果未绑 ...

  9. 第四章:Django表单 - 1:使用表单

    假设你想从表单接收用户名数据,一般情况下,你需要在HTML中手动编写一个如下的表单元素: <form action="/your-name/" method="po ...

随机推荐

  1. SpringBoot在IDEA中实现热部署

    gradle构建形式 添加依赖 compile("org.springframework.boot:spring-boot-devtools") 其他设置 步骤1 步骤2 按下 C ...

  2. Android如何降低service被杀死概率

    http://www.jianshu.com/p/06a1a434e057 http://www.cnblogs.com/ylligang/articles/2665181.html Android应 ...

  3. Java打印M图形(二维数组)——(九)

    对于平面图形输出集合图形与数字组合的,用二维数组.先在Excel表格中分析一下,找到简单的规律.二维数组的行数为行高,列数为最后一个数大小. 对于减小再增大再减小再增大的,可以用一个boolean标志 ...

  4. 【转】scapy 构造以太网注入帧

    1. 描述 使用scapy进行以太网帧的注入,相对于RAW_SOCKET还是比较简单的.在讲述packet注入之前,先了解一下scapy伪造以太网帧的相关知识.下图为以太网帧格式和scapy对应的封装 ...

  5. 深层揭密extern "C"

    一. extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的:其次,被它修饰的目标是“C”的.让我们来详细解读这两重含义. (1) 被ext ...

  6. ubuntu16.04安装opencv2.4.13

    1.更新 sudo apt-get update sudo apt-get upgrade 2.安装关联库 2.1 搭建C/C++编译环境 sudo apt-get install build-ess ...

  7. 内核中 subsys_initcall 以及初始化标号

    今天在看内核中无线的实现时,发现一个调用 subsys_initcall(cfg80211_init);搜索一些资料: subsys_initcall 的定义在 include/linux/init. ...

  8. CentOS 6.5下PXE+Kickstart无人值守安装操作系统centos7.3

    CentOS 6.5下PXE+Kickstart无人值守安装操作系统centos7.3 一.简介 1.1 什么是PXE PXE(Pre-boot Execution Environment,预启动执行 ...

  9. oracle中REGEXP_SUBSTR方法的使用

    近期在做商旅机票平台,遇到这样一个问题: 有一张tt_ticket表,用来存机票信息.里边有一个字段叫schedule,表示的是行程,存储格式为:北京/虹桥 由于公司位于上海.而上海眼下有两个机场:浦 ...

  10. Java8实战系列一

    从java7到java8,最主要的变化可以总结为 □Lambda表达式 □ 方法引用 □流和默认方法 让我们通过一个小例子感受一下 情景 1 集合对象排序 (对list中的苹果按照重量排序) Coll ...