在Django的视图中使用form对象的方法


Posted in Python onJuly 18, 2015

在学习了关于Form类的基本知识后,你会看到我们如何把它用到视图中,取代contact()代码中不整齐的部分。 一下示例说明了我们如何用forms框架重写contact():

# views.py

from django.shortcuts import render_to_response
from mysite.contact.forms import ContactForm

def contact(request):
  if request.method == 'POST':
    form = ContactForm(request.POST)
    if form.is_valid():
      cd = form.cleaned_data
      send_mail(
        cd['subject'],
        cd['message'],
        cd.get('email', 'noreply@example.com'),
        ['siteowner@example.com'],
      )
      return HttpResponseRedirect('/contact/thanks/')
  else:
    form = ContactForm()
  return render_to_response('contact_form.html', {'form': form})

 
# contact_form.html

<html>
<head>
  <title>Contact us</title>
</head>
<body>
  <h1>Contact us</h1>

  {% if form.errors %}
    <p style="color: red;">
      Please correct the error{{ form.errors|pluralize }} below.
    </p>
  {% endif %}

  <form action="" method="post">
    <table>
      {{ form.as_table }}
    </table>
    <input type="submit" value="Submit">
  </form>
</body>
</html>

看看,我们能移除这么多不整齐的代码! Django的forms框架处理HTML显示、数据校验、数据清理和表单错误重现。

尝试在本地运行。 装载表单,先留空所有字段提交空表单;继而填写一个错误的邮箱地址再尝试提交表单;最后再用正确数据提交表单。 (根据服务器的设置,当send_mail()被调用时,你将得到一个错误提示。而这是另一个问题。)
改变字段显示

你可能首先注意到:当你在本地显示这个表单的时,message字段被显示成`` input type=”text”`` ,而它应该被显示成<`` textarea`` >。我们可以通过设置* widget* 来修改它:

from django import forms

class ContactForm(forms.Form):
  subject = forms.CharField()
  email = forms.EmailField(required=False)
  message = forms.CharField(**widget=forms.Textarea** )

forms框架把每一个字段的显示逻辑分离到一组部件(widget)中。 每一个字段类型都拥有一个默认的部件,我们也可以容易地替换掉默认的部件,或者提供一个自定义的部件。

考虑一下Field类表现* 校验逻辑* ,而部件表现* 显示逻辑* 。
设置最大长度

一个最经常使用的校验要求是检查字段长度。 另外,我们应该改进ContactForm,使subject限制在100个字符以内。 为此,仅需为CharField提供max_length参数,像这样:

from django import forms

class ContactForm(forms.Form):
  subject = forms.CharField(**max_length=100** )
  email = forms.EmailField(required=False)
  message = forms.CharField(widget=forms.Textarea)

选项min_length参数同样可用。
设置初始值

让我们再改进一下这个表单:为字subject段添加* 初始值* : "I love your site!" (一点建议,但没坏处。)为此,我们可以在创建Form实体时,使用initial参数:

def contact(request):
  if request.method == 'POST':
    form = ContactForm(request.POST)
    if form.is_valid():
      cd = form.cleaned_data
      send_mail(
        cd['subject'],
        cd['message'],
        cd.get('email', `'noreply@example.com`_'),
        [`'siteowner@example.com`_'],
      )
      return HttpResponseRedirect('/contact/thanks/')
  else:
    form = ContactForm(
      **initial={'subject': 'I love your site!'}**
    )
  return render_to_response('contact_form.html', {'form': form})

现在,subject字段将被那个句子填充。

请注意,传入* 初始值* 数据和传入数据以* 绑定* 表单是有区别的。 最大的区别是,如果仅传入* 初始值* 数据,表单是unbound的,那意味着它没有错误消息。
自定义校验规则

假设我们已经发布了反馈页面了,email已经开始源源不断地涌入了。 这里有一个问题: 一些提交的消息只有一两个字,我们无法得知详细的信息。 所以我们决定增加一条新的校验: 来点专业精神,最起码写四个字,拜托。

我们有很多的方法把我们的自定义校验挂在Django的form上。 如果我们的规则会被一次又一次的使用,我们可以创建一个自定义的字段类型。 大多数的自定义校验都是一次性的,可以直接绑定到form类.

我们希望`` message`` 字段有一个额外的校验,我们增加一个`` clean_message()`` 方法到`` Form`` 类:

from django import forms

class ContactForm(forms.Form):
  subject = forms.CharField(max_length=100)
  email = forms.EmailField(required=False)
  message = forms.CharField(widget=forms.Textarea)

  def clean_message(self):
    message = self.cleaned_data['message']
    num_words = len(message.split())
    if num_words < 4:
      raise forms.ValidationError("Not enough words!")
    return message

Django的form系统自动寻找匹配的函数方法,该方法名称以clean_开头,并以字段名称结束。 如果有这样的方法,它将在校验时被调用。

特别地,clean_message()方法将在指定字段的默认校验逻辑执行* 之后* 被调用。(本例中,在必填CharField这个校验逻辑之后。)因为字段数据已经被部分处理,所以它被从self.cleaned_data中提取出来了。同样,我们不必担心数据是否为空,因为它已经被校验过了。

我们简单地使用了len()和split()的组合来计算单词的数量。 如果用户输入字数不足,我们抛出一个forms.ValidationError型异常。这个异常的描述会被作为错误列表中的一项显示给用户。

在函数的末尾显式地返回字段的值非常重要。 我们可以在我们自定义的校验方法中修改它的值(或者把它转换成另一种Python类型)。 如果我们忘记了这一步,None值就会返回,原始的数据就丢失掉了。
指定标签

HTML表单中自动生成的标签默认是按照规则生成的:用空格代替下划线,首字母大写。如email的标签是"Email" 。(好像在哪听到过? 是的,同样的逻辑被用于模块(model)中字段的verbose_name值。 我们在第五章谈到过。)

像在模块中做过的那样,我们同样可以自定义字段的标签。 仅需使用label,像这样:

class ContactForm(forms.Form):
  subject = forms.CharField(max_length=100)
  email = forms.EmailField(required=False, **label='Your e-mail address'** )
  message = forms.CharField(widget=forms.Textarea)

 

Python 相关文章推荐
python 遍历字符串(含汉字)实例详解
Apr 04 Python
Python算法之求n个节点不同二叉树个数
Oct 27 Python
Python机器学习logistic回归代码解析
Jan 17 Python
python bmp转换为jpg 并删除原图的方法
Oct 25 Python
python导入坐标点的具体操作
May 10 Python
利用anaconda保证64位和32位的python共存
Mar 09 Python
Python音频操作工具PyAudio上手教程详解
Jun 26 Python
python执行scp命令拷贝文件及文件夹到远程主机的目录方法
Jul 08 Python
python实现微信自动回复机器人功能
Jul 11 Python
Django框架教程之中间件MiddleWare浅析
Dec 29 Python
Python3 ffmpeg视频转换工具使用方法解析
Aug 10 Python
Python基于staticmethod装饰器标示静态方法
Oct 17 Python
详解Django中的form库的使用
Jul 18 #Python
在Django框架中编写Contact表单的教程
Jul 17 #Python
简单解析Django框架中的表单验证
Jul 17 #Python
改进Django中的表单的简单方法
Jul 17 #Python
Python的Django框架中的表单处理示例
Jul 17 #Python
Python中max函数用法实例分析
Jul 17 #Python
详解Django中Request对象的相关用法
Jul 17 #Python
You might like
锁定年轻人的双倍活力 星巴克推出星倍醇即饮浓咖啡
2021/03/03 咖啡文化
PHP中文乱码解决方案
2015/03/05 PHP
PHP结合Mysql数据库实现留言板功能
2016/03/04 PHP
php使用pclzip类实现文件压缩的方法(附pclzip类下载地址)
2016/04/30 PHP
打开超链需要“确认”对话框的方法
2007/03/08 Javascript
网页自动刷新,不产生嗒嗒声的一个解决方法
2007/03/27 Javascript
js 实现打印网页中定义的部分内容的代码
2010/04/01 Javascript
基于jQuery替换table中的内容并显示进度条的代码
2011/08/02 Javascript
javascript动态向网页中添加表格实现代码
2014/02/19 Javascript
js用闭包遍历树状数组的方法
2014/03/19 Javascript
Javascript实现的简单右键菜单类
2015/09/23 Javascript
AngularJS基础 ng-show 指令简单示例
2016/08/03 Javascript
原生js实现jquery函数animate()动画效果的简单实例
2016/08/21 Javascript
VUE元素的隐藏和显示(v-show指令)
2017/06/23 Javascript
vue 2.0封装model组件的方法
2017/08/03 Javascript
详解js获取video任意时间的画面截图
2019/04/17 Javascript
原生js实现抽奖小游戏
2019/06/27 Javascript
[01:58]最残酷竞争 2016国际邀请赛中国区预选赛积分循环赛回顾
2016/06/28 DOTA
Python爬虫实现百度图片自动下载
2018/02/04 Python
python如何创建TCP服务端和客户端
2018/08/26 Python
Python 做曲线拟合和求积分的方法
2018/12/29 Python
python配置文件写入过程详解
2019/10/19 Python
Python 脚本实现淘宝准点秒杀功能
2019/11/13 Python
Python requests模块session代码实例
2020/04/14 Python
pytorch下的unsqueeze和squeeze的用法说明
2021/02/06 Python
CSS3 实现穿梭星空动画
2020/11/13 HTML / CSS
柒牌官方商城:中国男装优秀品牌
2017/06/30 全球购物
优秀毕业生求职推荐信范文
2013/11/21 职场文书
银行求职推荐信范文
2013/11/30 职场文书
技校毕业生个人学习的自我评价
2014/02/21 职场文书
2016北大自主招生自荐信模板
2016/01/28 职场文书
公文写作:教你写“建议书”
2019/05/07 职场文书
Python机器学习之KNN近邻算法
2021/05/14 Python
python中24小时制转换为12小时制的方法
2021/06/18 Python
分享Python获取本机IP地址的几种方法
2022/03/17 Python
阿里云服务器部署RabbitMQ集群的详细教程
2022/06/01 Servers