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通过90行代码搭建一个音乐搜索工具
Jul 29 Python
浅谈python为什么不需要三目运算符和switch
Jun 17 Python
Python更新数据库脚本两种方法及对比介绍
Jul 27 Python
python+POP3实现批量下载邮件附件
Jun 19 Python
Python3利用print输出带颜色的彩色字体示例代码
Apr 08 Python
Python实现快速排序的方法详解
Oct 25 Python
Python3 使用map()批量的转换数据类型,如str转float的实现
Nov 29 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧(自定义信号与槽)详解与实例
Mar 06 Python
django orm模块中的 is_delete用法
May 20 Python
一篇文章教你用python画动态爱心表白
Nov 22 Python
Pytorch之扩充tensor的操作
Mar 04 Python
Python 数据可视化之Bokeh详解
Nov 02 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
深入理解PHP之数组(遍历顺序)  Laruence原创
2012/06/13 PHP
php常用的url处理函数总结
2014/11/19 PHP
windows下apache搭建php开发环境
2015/08/27 PHP
PHP创建PowerPoint2007文档的方法
2015/12/10 PHP
php设计模式之策略模式应用案例详解
2019/06/17 PHP
PHP使用 Pear 进行安装和卸载包的方法详解
2019/07/08 PHP
PHP Beanstalkd消息队列的安装与使用方法实例详解
2020/02/21 PHP
简单的前端js+ajax 购物车框架(入门篇)
2011/10/29 Javascript
同域jQuery(跨)iframe操作DOM(示例代码)
2013/12/13 Javascript
JavaScript框架(iframe)操作总结
2014/04/16 Javascript
js实现百度联盟中一款不错的图片切换效果完整实例
2015/03/04 Javascript
javascript实现checkBox的全选,反选与赋值
2015/03/12 Javascript
解决jQuery使用JSONP时产生的错误
2015/12/02 Javascript
jQuery插件fullPage.js实现全屏滚动效果
2016/12/02 Javascript
Vue与Node.js通过socket.io通信的示例代码
2018/07/25 Javascript
简单说说angular.json文件的使用
2018/10/29 Javascript
jQuery实现当拉动滚动条到底部加载数据的方法分析
2019/01/24 jQuery
javascript设计模式 ? 中介者模式原理与用法实例分析
2020/04/20 Javascript
vue和H5 draggable实现拖拽并替换效果
2020/07/29 Javascript
全面解读Python Web开发框架Django
2014/06/30 Python
wxPython的安装图文教程(Windows)
2017/12/28 Python
python3.6 如何将list存入txt后再读出list的方法
2019/07/02 Python
解决python对齐错误的方法
2020/07/16 Python
Python pymysql模块安装并操作过程解析
2020/10/13 Python
巴西最大的在线约会网站:ParPerfeito
2018/07/11 全球购物
成功的酒店创业计划书
2013/12/27 职场文书
旅游管理专业生自荐信范文
2014/01/02 职场文书
国旗下的讲话演讲稿
2014/05/08 职场文书
贷款委托书怎么写
2014/08/02 职场文书
小学三好学生事迹材料
2014/08/15 职场文书
新颖的化妆品活动方案
2014/08/21 职场文书
教师学习三严三实心得体会
2014/10/13 职场文书
2015年挂职锻炼工作总结
2014/12/12 职场文书
入党政审材料范文
2014/12/24 职场文书
趣味运动会简讯
2015/07/20 职场文书
使用CSS自定义属性实现骨架屏效果
2022/06/21 HTML / CSS