Python的Django框架中的表单处理示例


Posted in Python onJuly 17, 2015

组建一个关于书籍、作者、出版社的例子:

from django.db import models

class Publisher(models.Model):
  name = models.CharField(max_length=30)
  address = models.CharField(max_length=50)
  city = models.CharField(max_length=60)
  state_province = models.CharField(max_length=30)
  country = models.CharField(max_length=50)
  website = models.URLField()

class Author(models.Model):
  first_name = models.CharField(max_length=30)
  last_name = models.CharField(max_length=40)
  email = models.EmailField()

class Book(models.Model):
  title = models.CharField(max_length=100)
  authors = models.ManyToManyField(Author)
  publisher = models.ForeignKey(Publisher)
  publication_date = models.DateField()

我们现在来创建一个简单的view函数以便让用户可以通过书名从数据库中查找书籍。
通常,表单开发分为两个部分: 前端HTML页面用户接口和后台view函数对所提交数据的处理过程。 第一部分很简单;现在我们来建立个view来显示一个搜索表单:

from django.shortcuts import render_to_response

def search_form(request):
  return render_to_response('search_form.html')

这个view函数可以放到Python的搜索路径的任何位置。 为了便于讨论,咱们将它放在 books/views.py 里。

这个 search_form.html 模板,可能看起来是这样的:

<html>
<head>
  <title>Search</title>
</head>
<body>
  <form action="/search/" method="get">
    <input type="text" name="q">
    <input type="submit" value="Search">
  </form>
</body>
</html>

而 urls.py 中的 URLpattern 可能是这样的:

from mysite.books import views

urlpatterns = patterns('',
  # ...
  (r'^search-form/$', views.search_form),
  # ...
)

(注意,我们直接将views模块import进来了,而不是用类似 from mysite.views import search_form 这样的语句,因为前者看起来更简洁。)

现在,如果你运行 runserver 命令,然后访问http://127.0.0.1:8000/search-form/,你会看到搜索界面。 非常简单。

不过,当你通过这个form提交数据时,你会得到一个Django 404错误。 这个Form指向的URL /search/ 还没有被实现。 让我们添加第二个视图函数并设置URL:

# urls.py

urlpatterns = patterns('',
  # ...
  (r'^search-form/$', views.search_form),
  (r'^search/$', views.search),
  # ...
)

# views.py

def search(request):
  if 'q' in request.GET:
    message = 'You searched for: %r' % request.GET['q']
  else:
    message = 'You submitted an empty form.'
  return HttpResponse(message)

暂时先只显示用户搜索的字词,以确定搜索数据被正确地提交给了Django,这样你就会知道搜索数据是如何在这个系统中传递的。 简而言之:

    在HTML里我们定义了一个变量q。当提交表单时,变量q的值通过GET(method=”get”)附加在URL /search/上。

    处理/search/(search())的视图通过request.GET来获取q的值。

需要注意的是在这里明确地判断q是否包含在request.GET中。就像上面request.META小节里面提到,对于用户提交过来的数据,甚至是正确的数据,都需要进行过滤。 在这里若没有进行检测,那么用户提交一个空的表单将引发KeyError异常:

# BAD!
def bad_search(request):
  # The following line will raise KeyError if 'q' hasn't
  # been submitted!
  message = 'You searched for: %r' % request.GET['q']
  return HttpResponse(message)

查询字符串参数

因为使用GET方法的数据是通过查询字符串的方式传递的(例如/search/?q=django),所以我们可以使用requet.GET来获取这些数据。我们知道在视图里可以使用request.GET来获取传统URL里的查询字符串(例如hours=3)。

获取使用POST方法的数据与GET的相似,只是使用request.POST代替了request.GET。那么,POST与GET之间有什么不同?当我们提交表单仅仅需要获取数据时就可以用GET; 而当我们提交表单时需要更改服务器数据的状态,或者说发送e-mail,或者其他不仅仅是获取并显示数据的时候就使用POST。 在这个搜索书籍的例子里,我们使用GET,因为这个查询不会更改服务器数据的状态。 (如果你有兴趣了解更多关于GET和POST的知识,可以参见http://www.w3.org/2001/tag/doc/whenToUseGet.html。)

既然已经确认用户所提交的数据是有效的,那么接下来就可以从数据库中查询这个有效的数据(同样,在views.py里操作):

from django.http import HttpResponse
from django.shortcuts import render_to_response
from mysite.books.models import Book

def search(request):
  if 'q' in request.GET and request.GET['q']:
    q = request.GET['q']
    books = Book.objects.filter(title__icontains=q)
    return render_to_response('search_results.html',
      {'books': books, 'query': q})
  else:
    return HttpResponse('Please submit a search term.')

让我们来分析一下上面的代码:

  •     除了检查q是否存在于request.GET之外,我们还检查来reuqest.GET[‘q']的值是否为空。
  •     我们使用Book.objects.filter(title__icontains=q)获取数据库中标题包含q的书籍。 icontains是一个查询关键字。这个语句可以理解为获取标题里包含q的书籍,不区分大小写。
  •     这是实现书籍查询的一个很简单的方法。 我们不推荐在一个包含大量产品的数据库中使用icontains查询,因为那会很慢。 (在真实的案例中,我们可以使用以某种分类的自定义查询系统。 在网上搜索“开源 全文搜索”看看是否有好的方法)

    最后,我们给模板传递来books,一个包含Book对象的列表。 查询结果的显示模板search_results.html如下所示:

<p>You searched for: <strong>{{ query }}</strong></p>

{% if books %}
  <p>Found {{ books|length }} book{{ books|pluralize }}.</p>
  <ul>
    {% for book in books %}
    <li>{{ book.title }}</li>
    {% endfor %}
  </ul>
{% else %}
  <p>No books matched your search criteria.</p>
{% endif %}

    注意这里pluralize的使用,这个过滤器在适当的时候会输出s(例如找到多本书籍)。

Python 相关文章推荐
推荐下python/ironpython:从入门到精通
Oct 02 Python
Python求两个list的差集、交集与并集的方法
Nov 01 Python
ansible作为python模块库使用的方法实例
Jan 17 Python
Android分包MultiDex策略详解
Oct 30 Python
Python使用Scrapy保存控制台信息到文本解析
Dec 27 Python
对numpy的array和python中自带的list之间相互转化详解
Apr 13 Python
Python实现获取nginx服务器ip及流量统计信息功能示例
May 18 Python
TensorFlow 滑动平均的示例代码
Jun 19 Python
Python3.7中安装openCV库的方法
Jul 11 Python
python中sort和sorted排序的实例方法
Aug 26 Python
教你怎么用python实现字符串转日期
May 24 Python
Python中使用ipython的详细教程
Jun 22 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
Django中更新多个对象数据与删除对象的方法
Jul 17 #Python
Django框架中数据的连锁查询和限制返回数据的方法
Jul 17 #Python
You might like
DC宇宙的第一个英雄,堪称动漫史鼻祖,如今成为美国文化的象征
2020/04/09 欧美动漫
用PHP动态创建Flash动画
2006/10/09 PHP
php中静态类与静态变量用法的区别分析
2015/01/15 PHP
PHP实现的蚂蚁爬杆路径算法代码
2015/12/03 PHP
微信小程序 消息推送php服务器验证实例详解
2017/03/30 PHP
PHP实现简单日历类编写
2020/08/28 PHP
jquery 与NVelocity 产生冲突的解决方法
2011/06/13 Javascript
浅谈Javascript事件处理程序的几种方式
2012/06/27 Javascript
jQuery动画效果-slideUp slideDown上下滑动示例代码
2013/08/28 Javascript
js onmousewheel事件多次触发问题解决方法
2014/10/17 Javascript
jQuery中:first选择器用法实例
2014/12/30 Javascript
jQuery自动完成插件completer附源码下载
2016/01/04 Javascript
移动端js图片查看器
2016/11/17 Javascript
移动端基础事件总结与应用
2017/01/12 Javascript
jQuery的$.extend 浅拷贝与深拷贝
2017/03/08 Javascript
Vue2 Vue-cli中使用Typescript的配置详解
2017/07/24 Javascript
在Js页面通过POST传递参数跳转到新页面详解
2017/08/25 Javascript
使用原生js+canvas实现模拟心电图的实例
2017/09/20 Javascript
解决vue-router进行build无法正常显示路由页面的问题
2018/03/06 Javascript
vue 属性拦截实现双向绑定的实例代码
2018/10/24 Javascript
js操作两个json数组合并、去重,以及删除某一项元素
2020/09/22 Javascript
[57:41]Secret vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
从零学Python之入门(四)运算
2014/05/27 Python
Python IDLE入门简介
2017/12/08 Python
记一次python 内存泄漏问题及解决过程
2018/11/29 Python
python爬虫之遍历单个域名
2019/11/20 Python
Python虚拟环境库virtualenvwrapper安装及使用
2020/06/17 Python
Python基于Faker假数据构造库
2020/11/30 Python
HTML5网页音乐播放器的示例代码
2017/11/09 HTML / CSS
为女性购买传统的印度服装和婚纱:Kalkifashion
2019/07/22 全球购物
新疆民族团结演讲稿
2014/08/27 职场文书
企业总经理助理岗位职责
2014/09/12 职场文书
2014年内勤工作总结
2014/11/24 职场文书
2014年学校体育工作总结
2014/12/08 职场文书
酒店前台岗位职责
2015/04/16 职场文书
领导干部失职检讨书
2015/05/05 职场文书