HTML表单一直是交互性网站的支柱,使用form组件对用户通过表单提交的数据进行访问、有效性检查以及其他处理

从Request对象中获取数据

URL相关信息
属性/方法 说明 举例
request.path 除域名外的请求路径,以正斜杠开头 "/hellow/"
request.get_host() 主机名(比如,通常所说的域名) "127.0.0.1:8000"or"www.example.com"
request.get_full_path() 请求路径,可能包含查询字符 "/hellow/?p=6"
request.is_secure() 如果通过HTTPS访问,返回True,否则返回False True或False

request.META是一个字典,包含了所有本次HTTP请求的Header信息,比如用户IP地址和用户Agent(通常是浏览器的名称和版本号),常见的有:

  • HTTP_USER_AGENT 用户浏览器的user-agent
  • REMOTE_ADDR 客户端IP

第一个Form类

表单框架最主要的用法是,为每一个将要处理的HTML的 <Form> 定义一个Form类。 在这个例子中,我们只

有一个 <Form> ,因此我们只需定义一个Form类。 这个类可以存在于任何地方,甚至直接写在 views.py

文件里也行,但惯例是把Form类都放到一个文件中:forms.py。在存放 views.py 的目录中,创建这

个文件,然后输入:

from django import forms
class RegisterForm(forms.Form):
username = forms.CharField()
pwd = forms.CharField()
email = forms.EmailField(required = False)

这看上去简单易懂,并且很像在模块中使用的语法。 表单中的每一个字段(域)作为Form类的属性,被展现

成Field类。这里只用到CharField和EmailField类型。 每一个字段都默认是必填。要使email成为可选项,我

们需要指定required=False。

>>> from new.forms import RegisterForm
>>> r = RegisterForm()
>>> r
<RegisterForm bound=False, valid=Unknown, fields=(username;pwd;email)>
>>> print(r)
Form对象做的第一件事是将自己显示成HTML:
<tr><th><label for="id_username">Username:</label></th><td><input type="text" name="username" required id="id_username"></td></tr>
<tr><th><label for="id_pwd">Pwd:</label></th><td><input type="text" name="pwd" required id="id_pwd"></td></tr>
<tr><th><label for="id_email">Email:</label></th><td><input type="email" name="email" required id="id_email"></td></tr>

为了便于访问,Django用 <label> 标志,为每一个字段添加了标签。 这个做法使默认行为尽可能合适。

默认输出按照HTML的< table >格式,另外有一些其它格式的输出:

>>> print(r.as_p())
<p><label for="id_username">Username:</label> <input type="text" name="username" required id="id_username"></p>
<p><label for="id_pwd">Pwd:</label> <input type="text" name="pwd" required id="id_pwd"></p>
<p><label for="id_email">Email:</label> <input type="email" name="email" required id="id_email"></p>

>>> print(r.as_ul())
![as_ul()](C:\Users\孙远新\OneDrive\Documents\django\图片\as_ul().jpg)<li><label for="id_username">Username:</label> <input type="text" name="username" required id="id_username"></li>
<li><label for="id_pwd">Pwd:</label> <input type="text" name="pwd" required id="id_pwd"></li>
<li><label for="id_email">Email:</label> <input type="email" name="email" required id="id_email"></li>

>>> print(r['username'])
<input type="text" name="username" required id="id_username">
Form对象做的第二件事是校验数据
>>> r.is_bound
True

调用任何绑定form的is_valid()方法,就可以知道它的数据是否合法。 我们已经为每个字段传入了值,因此整

个Form是合法的:

>>> r.is_valid()
True

如果我们不传入email值,它依然是合法的。因为我们指定这个字段的属性required=False;但是,如果留空username或pwd,整个Form就不再合法了:

>>> r = RegisterForm({'username':'Amy','pwd':'abc13',})
>>> r.is_valid()
True
>>> r = RegisterForm({'pwd':'abc13','email':'amy@123.com'})
>>> r.is_valid()
False

如果多出其他属性,Form依然是合法的,

>>> r = RegisterForm({'username':'Amy','pwd':'abc13','w':24})
>>> r.is_valid()
True

查看字段的出错消息,Form实体都有一个errors属性,它为你提供了一个字段与错误消息相映射的字典表

>>> r.errors
{'username': ['This field is required.']}

你可以逐一查看每个字段的出错消息

>>> r['username'].errors
['This field is required.']
>>> r['pwd'].errors
[]

如果一个Form实体的数据是合法的,它就会有一个可用的cleaned_data属性。 这是一个包含干净的提交

数据的字典。 Django的form框架不但校验数据,它还会把它们转换成相应的Python类型数据,这叫做清理数

据。例如Form实体的数据合法的情况下,可以清除掉{%csrf_token%}对应的name='csrfmiddlewaretoken'

>>> r.cleaned_data
{'pwd': 'abc13', 'email': 'amy@123.com'}

如果我们使用整数型或日期型,form框架会确保方法使用合适的Python整数型或datetime.date型对象。

在视图中使用Form对象

from django.shortcuts import render,redirect
from mysite.new.forms import RegisterForm
def register(request):
if request.method == 'POST':
form = RegisterForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
#创建用户 User.objects.creates(**cd)
return redirect('/home/')
else:
return render(request,'register.html', {'form': form,})
form = RegisterForm()
return render(request,'register.html', {'form': form})
//register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="" method='post' novalidate>
<p><label for="">用户名</label>{{form.username}}<span class="error">{{form.errors.username.0}}</span></p>
<p><label for="">密码</label>{{form.pwd}}<span class="error">{{form.errors.pwd.0}}</span> </p>
<p><label for="">邮箱</label>{{form.pwd}}<span class="error">{{form.errors.email.0}}</span> </p>
<input type="submit" value="确定">
</form>
</body>
</html>

在浏览器中查看{{form.username}}

<input name="username" id="id_username" required="" type="text" value="xxx">

使用Form对象作为模板的好处:

  • input标签name属性的值自动与Form类中的字段保持一致,简化视图函数的代码
  • form.is_valid()为False,对输入的值进行返回,渲染在刷新面后的页面上

input标签的type默认为"text",输入密码时要求为密文的形式,必须进行更改,此外为了页面的整体样式,还需要增加一些其他的属性

显示逻辑
class RegisterForm(forms.Form):
#添加标签类名
username = forms.CharField(label="用户名",widget=forms.TextInput(attrs={"class":"form-control"}),error_messages={'required':'该字段不能为空'})
#
pwd = forms.CharField(widget=forms.PasswordInput)
email = forms.EmailField(required=False,error_messages={"invalid":"邮箱格式错误"})
自定义校验逻辑
#max_length=16
#min_length=8
from django import forms
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
class RegisterForm(forms.Form):
username = forms.CharField(min_length=8,error_messages={'required':'该字段不能为空'})
pwd = forms.CharField(widget=forms.PasswordInput)
email = forms.EmailField(required=False,error_messages={"invalid":"邮箱格式错误"})
def clean_username(self):
username = self.cleaned_data['username']
if Userinfo.objects.filter(username = username):
raise ValidationError("用户名已存在!")
else:
return username

Django的form系统自动寻找匹配的函数方法,该方法名称以clean_开头,并以字段名称结束。 如果有这样的

方法,它将在校验时被调用。

特别地,clean_username()方法将在指定字段的默认校验逻辑执行 之后*被调用。(本例中,在必

填CharField这个校验逻辑之后。)因为字段数据已经被部分处理,所以它被从self.cleaned_data中提取出来

了。同样,我们不必担心数据是否为空,因为它已经被校验过了。

forms.ValidationError型异常。这个异常的描述会被作为错误列表中的一项显示给用户

在函数的末尾显式地返回字段的值非常重要。 我们可以在我们自定义的校验方法中修改它的值(或者把它转换

成另一种Python类型)。 如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了。

指定标签

HTML表单中自动生成的标签默认是按照规则生成的:用空格代替下划线,首字母大写。如email的标签

是"Email" 。

自定义字段的标签

email = forms.EmailField(required=False, label='Your e‐mail address'*)
定制Form设计
class RegisterForm(forms.Form):
username = forms.CharField(min_length=8,error_messages={'required':'该字段不能为空'},
widget=forms.TextInput(attrs={'placeholder':'输入用户名'})
pwd = forms.CharField(widget=forms.PasswordInput)
email = forms.EmailField(required=False,error_messages={"invalid":"邮箱格式错误"})
'''
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
field.widget.attrs.update({'class': 'form-control'})
'''

Django框架4——form表单的更多相关文章

  1. 第三百一十一节,Django框架,Form表单验证

    第三百一十一节,Django框架,Form表单验证 表单提交 html <!DOCTYPE html> <html lang="en"> <head& ...

  2. Django框架 之 Form表单和Ajax上传文件

    Django框架 之 Form表单和Ajax上传文件 浏览目录 Form表单上传文件 Ajax上传文件 伪造Ajax上传文件 Form表单上传文件 html 1 2 3 4 5 6 7 <h3& ...

  3. python3开发进阶-Django框架的Form表单系统和基本操作

    阅读目录 什么是Form组件 常用字段和插件 自定义校验的方式 补充进阶 一.什么是Form组件 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标 ...

  4. 九 Django框架,Form表单验证

    表单提交 html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. django框架中form表单Post方法无法提交 Forbidden (403) CSRF verification failed. Request aborted.

    问题如图: 解决方法: 在视图函数中引入并使用装饰器 from django.views.decorators.csrf import csrf_exempt @csrf_exempt

  6. Django组件之Form表单

    一.Django中的Form表单介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用户的输入 ...

  7. Python的Django框架中forms表单类的使用方法详解

    用户表单是Web端的一项基本功能,大而全的Django框架中自然带有现成的基础form对象,本文就Python的Django框架中forms表单类的使用方法详解. Form表单的功能 自动生成HTML ...

  8. Django中的Form表单

    Django中已经定义好了form类,可以很容易的使用Django生成一个表单. 一.利用Django生成一个表单: 1.在应用下创建一个forms文件,用于存放form表单.然后在forms中实例华 ...

  9. Django中的Form表单验证

    回忆一下Form表单验证的逻辑: 前端有若干个input输入框,将用户输入内容,以字典传递给后端. 后端预先存在一个Form表单验证的基类,封装了一个检测用户输入是否全部通过的方法.该方法会先定义好错 ...

随机推荐

  1. [NPM + React] Prepare a Custom React Hook to be Published as an npm Package

    Before we publish our package, we want to make sure everything is set up correctly. We’ll cover vers ...

  2. WinDbg常用命令系列---日志操作相关命令log*

    .logopen (Open Log File) .logopen命令将事件和命令的副本从调试器命令窗口发送到新的日志文件. .logopen [Options] [FileName] .logope ...

  3. pgloader 学习(九) pg 2 pg 使用with 参数控制同步逻辑

    pgloader 支持比较丰富的配置参数,同时默认数据在同步的时候是会进行索.schema 以及数据的同步对于实际我们可能存在需要进行控制,我们可以通过with 参数方便的处理 参考配置 load 文 ...

  4. repo源

    [sdata-base] name=Base baseurl=http://xx.xx.xx.xx:4507/repo/$releasever/$basearch/base enabled=1 gpg ...

  5. 在nodejs中操作数据库(MongoDB和MySQL为例)

    一.使用nodejs操作MongoDB数据库 ①使用官方的mongodb包来操作 ②使用第三方的mongoose包来操作(比较常用) // 首先必须使MongoDB数据库保持开启状态 // npm下载 ...

  6. react用脚手架创建一个react单页面项目,react起手式

    官网地址:https://react.docschina.org/ 确保本地安装了Node.js node的版本大于8.10    npm的版本大于5.6 1.在本地的某个位置创建一个文件夹,执行以下 ...

  7. lower_bound( )和upper_bound( )怎么用嘞↓↓↓

    lower_bound( )和upper_bound( )都是利用二分查找的方法在一个排好序的数组中进行查找的. 在从小到大的排序数组中, lower_bound( begin,end,num):从数 ...

  8. 事务控制语言(TCL)

    一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行.如:转账. 原子性(Atomicity):一个事务要么都执行,要么都回滚(不可再分割) 一致性(Consistency) ...

  9. httpd.exe你的电脑中缺失msvcr110.dll怎么办(WIN2008服务器环境装WAMP2.5出现的问题)

    httpd.exe你的电脑中缺失msvcr110.dll怎么办 去微软官方下载相应的文件 1 打开上面说的网址 Download and install, if you not have it alr ...

  10. 【2019.11.18】SDN阅读作业

    为什么需要SDN?SDN特点? 随着网络的快速发展,传统互联网出现了如传统网络配置复杂度高等诸多问题,这些问题说明网络架构需要革新,可编程网络的相关研究为 SDN 的产生提供了可参考的理论依据 SDN ...