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脚本对Linux服务器进行监控的教程
Apr 02 Python
详细介绍Ruby中的正则表达式
Apr 10 Python
Using Django with GAE Python 后台抓取多个网站的页面全文
Feb 17 Python
Python 删除整个文本中的空格,并实现按行显示
Jul 24 Python
Django中使用第三方登录的示例代码
Aug 20 Python
python利用ffmpeg进行录制屏幕的方法
Jan 10 Python
把django中admin后台界面的英文修改为中文显示的方法
Jul 26 Python
解决torch.autograd.backward中的参数问题
Jan 07 Python
Python偏函数Partial function使用方法实例详解
Jun 17 Python
python实现邮件循环自动发件功能
Sep 11 Python
提高python代码运行效率的一些建议
Sep 29 Python
python 下载文件的几种方法汇总
Jan 06 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
phpMyAdmin 链接表的附加功能尚未激活问题的解决方法(已测)
2012/03/27 PHP
Docker配置PHP开发环境教程
2016/12/21 PHP
thinkphp中U方法按路由规则生成url的方法
2018/03/12 PHP
PHP递归算法的简单实例
2019/02/28 PHP
PHP面向对象程序设计重载(overloading)操作详解
2019/06/13 PHP
封装了一个js图片轮换效果的函数
2011/09/28 Javascript
JS实现图片横向滚动效果示例代码
2013/09/04 Javascript
PHP abstract与interface之间的区别
2013/11/11 Javascript
Javascript call和apply区别及使用方法
2013/11/14 Javascript
用正则表达式替换图片地址img标签
2013/11/22 Javascript
js写的评论分页(还不错)
2013/12/23 Javascript
js父页面与子页面不同时显示的方法
2014/10/16 Javascript
jQuery之DOM对象和jQuery对象的转换与区别分析
2015/01/08 Javascript
自己编写的支持Ajax验证的JS表单验证插件
2015/05/15 Javascript
简单谈谈javascript中的变量、作用域和内存问题
2015/08/30 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
2016/08/05 Javascript
使用vue框架 Ajax获取数据列表并用BootStrap显示出来
2017/04/24 Javascript
angular.js指令中的controller、compile与link函数的不同之处
2017/05/10 Javascript
用vue封装插件并发布到npm的方法步骤
2017/10/18 Javascript
Element Card 卡片的具体使用
2020/07/26 Javascript
Openlayers绘制聚合标注
2020/09/28 Javascript
python执行get提交的方法
2015/04/29 Python
Python下的常用下载安装工具pip的安装方法
2015/11/13 Python
python调用系统ffmpeg实现视频截图、http发送
2018/03/06 Python
python实现linux下抓包并存库功能
2018/07/18 Python
python百行代码自制电脑端网速悬浮窗的实现
2020/05/12 Python
Python爬虫模拟登陆哔哩哔哩(bilibili)并突破点选验证码功能
2020/12/21 Python
如何用 Python 制作 GitHub 消息助手
2021/02/20 Python
Python页面加载的等待方式总结
2021/02/28 Python
家居设计专业个人自荐信范文
2013/11/26 职场文书
大学生创业计划书的用途
2014/01/08 职场文书
电大毕业生自我鉴定
2014/04/10 职场文书
政审证明范文
2015/06/19 职场文书
Django migrate报错的解决方案
2021/05/20 Python
TV动画《间谍过家家》公开PV
2022/03/20 日漫
MySQL实战记录之如何快速定位慢SQL
2022/03/23 MySQL