简单解析Django框架中的表单验证


Posted in Python onJuly 17, 2015

我们的搜索示例仍然相当地简单,特别从数据验证方面来讲;我们仅仅只验证搜索关键值是否为空。 然后许多HTML表单包含着比检测值是否为空更为复杂的验证。 我们都有在网站上见过类似以下的错误提示信息:

  •     请输入一个有效的email地址, foo' 并不是一个有效的e-mail地址。
  •     请输入5位数的U.S 邮政编码, 123并非是一个有效的邮政编码。
  •     请输入YYYY-MM-DD格式的日期。
  •     请输入8位数以上并至少包含一个数字的密码。

关于JavaScript验证

可以使用Javascript在客户端浏览器里对数据进行验证,这些知识已超出本书范围。 要注意: 即使在客户端已经做了验证,但是服务器端仍必须再验证一次。 因为有些用户会将JavaScript关闭掉,并且还有一些怀有恶意的用户会尝试提交非法的数据来探测是否有可以攻击的机会。

除了在服务器端对用户提交的数据进行验证(例如在视图里验证),我们没有其他办法。 JavaScript验证可以看作是额外的功能,但不能作为唯一的验证功能。

我们来调整一下search()视图,让她能够验证搜索关键词是否小于或等于20个字符。 (为来让例子更为显著,我们假设如果关键词超过20个字符将导致查询十分缓慢)。那么该如何实现呢? 最简单的方式就是将逻辑处理直接嵌入到视图里,就像这样:

def search(request):
  error = False
  if 'q' in request.GET:
    q = request.GET['q']
    if not q:
      error = True
    **elif len(q) > 20:**
      **error = True**
    else:
      books = Book.objects.filter(title__icontains=q)
      return render_to_response('search_results.html',
        {'books': books, 'query': q})
  return render_to_response('search_form.html',
    {'error': error})

现在,如果尝试着提交一个超过20个字符的搜索关键词,系统不会执行搜索操作,而是显示一条错误提示信息。 但是,search_form.html里的这条提示信息是:”Please submit a search term.”,这显然是错误的, 所以我们需要更精确的提示信息:

<html>
<head>
  <title>Search</title>
</head>
<body>
  {% if error %}
    <p style="color: red;">Please submit a search term 20 characters or shorter.</p>
  {% endif %}
  <form action="/search/" method="get">
    <input type="text" name="q">
    <input type="submit" value="Search">
  </form>
</body>
</html>

但像这样修改之后仍有一些问题。 我们包含万象的提示信息很容易使人产生困惑: 提交一个空表单怎么会出现一个关于20个字符限制的提示? 所以,提示信息必须是详细的,明确的,不会产生疑议。

问题的实质在于我们只使用来一个布尔类型的变量来检测是否出错,而不是使用一个列表来记录相应的错误信息。 我们需要做如下的调整:

def search(request):
  **errors = []**
  if 'q' in request.GET:
    q = request.GET['q']
    if not q:
      **errors.append('Enter a search term.')**
    elif len(q) > 20:
      **errors.append('Please enter at most 20 characters.')**
    else:
      books = Book.objects.filter(title__icontains=q)
      return render_to_response('search_results.html',
        {'books': books, 'query': q})
  return render_to_response('search_form.html',
    {**'errors': errors** })

接着,我们要修改一下search_form.html模板,现在需要显示一个errors列表而不是一个布尔判断。

<html>
<head>
  <title>Search</title>
</head>
<body>
  **{% if errors %}**
    **<ul>**
      **{% for error in errors %}**
      **<li>{{ error }}</li>**
      **{% endfor %}**
    **</ul>**
  **{% endif %}**
  <form action="/search/" method="get">
    <input type="text" name="q">
    <input type="submit" value="Search">
  </form>
</body>
</html>
Python 相关文章推荐
python算法学习之桶排序算法实例(分块排序)
Dec 18 Python
Python基本语法经典教程
Mar 11 Python
Python爬虫代理IP池实现方法
Jan 05 Python
Python编程之字符串模板(Template)用法实例分析
Jul 22 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
Nov 20 Python
python简单实现操作Mysql数据库
Jan 29 Python
Python 实现中值滤波、均值滤波的方法
Jan 09 Python
Django框架自定义session处理操作示例
May 27 Python
python 使用socket传输图片视频等文件的实现方式
Aug 07 Python
如何运行带参数的python脚本
Nov 15 Python
用python求一重积分和二重积分的例子
Dec 06 Python
Python实现分数序列求和
Feb 25 Python
改进Django中的表单的简单方法
Jul 17 #Python
Python的Django框架中的表单处理示例
Jul 17 #Python
Python中max函数用法实例分析
Jul 17 #Python
详解Django中Request对象的相关用法
Jul 17 #Python
Python实现SVN的目录周期性备份实例
Jul 17 #Python
Python的Django框架中设置日期和字段可选的方法
Jul 17 #Python
Python的Django框架下管理站点的基本方法
Jul 17 #Python
You might like
PHP单链表的实现代码
2016/07/05 PHP
Laravel下生成验证码的类
2017/11/15 PHP
php获得刚插入数据的id 的几种方法总结
2018/05/31 PHP
利用onresize使得div可以随着屏幕大小而自适应的代码
2010/01/15 Javascript
Web开发者必备的12款超赞jQuery插件
2010/12/03 Javascript
Google的跟踪代码 动态加载js代码方法应用
2012/11/12 Javascript
JS读取XML文件示例代码
2013/11/15 Javascript
javascript中处理时间戳为日期格式的方法
2014/01/02 Javascript
JavaScript网页定位详解
2014/01/13 Javascript
javascript中加号(+)操作符的一些神奇作用
2014/06/06 Javascript
浅谈JS日期(Date)处理函数
2014/12/07 Javascript
javascript控制台详解
2015/06/25 Javascript
深入理解Ajax的get和post请求
2016/06/02 Javascript
jQuery的图片轮播插件PgwSlideshow使用详解
2016/08/11 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
Bootstrap + AngularJS 实现简单的数据过滤字符查找功能
2017/07/27 Javascript
用Axios Element实现全局的请求loading的方法
2018/03/15 Javascript
vue实现分页栏效果
2019/06/28 Javascript
es6中let和const的使用方法详解
2020/02/24 Javascript
vue+axios 拦截器实现统一token的案例
2020/09/11 Javascript
Vue使用Ref跨层级获取组件的步骤
2021/01/25 Vue.js
[55:47]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第三局
2016/02/27 DOTA
django 解决manage.py migrate无效的问题
2018/05/27 Python
Python根据文件名批量转移图片的方法
2018/10/21 Python
基于python指定包的安装路径方法
2018/10/27 Python
python制作微博图片爬取工具
2021/01/16 Python
自荐信包含哪些内容
2013/10/30 职场文书
小学教师办公室制度
2014/02/03 职场文书
《埃及的金字塔》教学反思
2014/04/07 职场文书
大型活动组织方案
2014/05/10 职场文书
敬老院献爱心活动总结
2014/07/08 职场文书
解决Golang中ResponseWriter的一个坑
2021/04/27 Golang
为什么在foreach循环中JAVA集合不能添加或删除元素
2021/06/11 Java/Android
Python下opencv使用hough变换检测直线与圆
2021/06/18 Python
MySQL对数据表已有表进行分区表的实现
2021/11/01 MySQL
Hive HQL支持2种查询语句风格
2022/06/25 数据库