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将数组的元素导出到变量中(unpacking)
Oct 27 Python
Python更新数据库脚本两种方法及对比介绍
Jul 27 Python
python matplotlib坐标轴设置的方法
Dec 05 Python
Python3 实现随机生成一组不重复数并按行写入文件
Apr 09 Python
TensorFlow打印tensor值的实现方法
Jul 27 Python
pyqt5 从本地选择图片 并显示在label上的实例
Jun 13 Python
Django model select的多种用法详解
Jul 16 Python
tensorflow-gpu安装的常见问题及解决方案
Jan 20 Python
python如何调用java类
Jul 05 Python
Python创建临时文件和文件夹
Aug 05 Python
Python自动化测试基础必备知识点总结
Feb 07 Python
Python+Appium自动化测试的实战
Jun 30 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
利用discuz自带通行证整合dedecms的方法以及文件下载
2007/03/06 PHP
php图片验证码代码
2008/03/27 PHP
PHP中执行MYSQL事务解决数据写入不完整等情况
2014/01/07 PHP
php中in_array函数用法分析
2014/11/15 PHP
解决PHP 7编译安装错误:cannot stat ‘phar.phar’: No such file or directory
2017/02/25 PHP
Yii2.0框架实现带分页的多条件搜索功能示例
2019/02/20 PHP
javascript的键盘控制事件说明
2008/04/15 Javascript
jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明
2011/06/27 Javascript
JS对img标签进行优化使用onerror显示默认图像
2014/04/24 Javascript
js发送短信倒计时的简单实现方法
2016/09/08 Javascript
bootstrap学习使用(导航条、下拉菜单、轮播、栅格布局等)
2016/12/01 Javascript
jQuery实现可拖拽3D万花筒旋转特效
2017/01/03 Javascript
微信小程序 radio单选框组件详解及实例代码
2017/01/10 Javascript
微信小程序 两种滑动方式(横向滑动,竖向滑动)详细及实例代码
2017/01/13 Javascript
jquery submit()不能提交表单的解决方法
2017/04/24 jQuery
原生JS实现日历组件的示例代码
2017/09/22 Javascript
在react中使用vuex的示例代码
2018/07/30 Javascript
解决Layui选择全部,换页checkbox复选框重新勾选的问题方法
2018/08/14 Javascript
vue学习之Vue-Router用法实例分析
2020/01/06 Javascript
原生JS实现pc端轮播图效果
2020/12/21 Javascript
[02:32]“虐狗”镜头慎点 2016国际邀请赛中国区预选赛现场玩家采访
2016/06/28 DOTA
[00:17]DOTA2荣耀之路5:It’s a disastah!
2018/05/28 DOTA
用Python进行基础的函数式编程的教程
2015/03/31 Python
微信跳一跳python代码实现
2018/01/05 Python
Python实现获取nginx服务器ip及流量统计信息功能示例
2018/05/18 Python
实用自动化运维Python脚本分享
2018/06/04 Python
Python split() 函数拆分字符串将字符串转化为列的方法
2019/07/16 Python
Win 10下Anaconda虚拟环境的教程
2020/05/18 Python
Python爬虫JSON及JSONPath运行原理详解
2020/06/04 Python
利用Python实现Excel的文件间的数据匹配功能
2020/06/16 Python
python 中关于pycharm选择运行环境的问题
2020/10/31 Python
Linux面试经常问的文件系统操作命令
2015/11/05 面试题
镇政府副镇长群众路线专题民主生活会对照检查材料
2014/09/19 职场文书
2014年政教处工作总结
2014/12/20 职场文书
房地产销售主管岗位职责
2015/02/13 职场文书
党员考试作弊检讨书1000字
2015/02/16 职场文书