Python网络编程09----Django表单

本文介绍了Django中处理HTTP请求的HttpRequest对象,讲解了如何从Request对象中获取数据,包括URL信息和提交数据。接着讨论了如何改进表单,特别是数据验证的重要性,强调了服务器端验证的必要性。最后,探讨了Django的newforms库,展示了如何使用Form类简化表单处理和验证,包括自定义校验规则和表单设计。
摘要由CSDN通过智能技术生成


一、从Request对象中获取数据

        我们在讲述View的函数时已经介绍过HttpRequest对象了,但当时并没有讲太多。 让我们回忆下:每个view函数的第一个参数是一个HttpRequest对象,就像下面这个hello()函数:

from django.http import HttpResponse
def hello(request):
    return HttpResponse("Hello world")

        HttpRequest对象,比如上面代码里的request变量,会有一些有趣的、你必须让自己熟悉的属性和方法,以便知道能拿它们来做些什么。 在view函数的执行过程中,你可以用这些属性来获取当前request的一些信息(比如,你正在加载这个页面的用户是谁,或者用的是什么浏览器)。

1. URL相关信息

      HttpRequest对象包含当前请求URL的一些信息:

属性/方法 说明 举例
request.path 除域名以外的请求路径,以正斜杠开头 "/hello/"
request.get_host() 主机名(比如,通常所说的域名) "127.0.0.1:8000" or "www.example.com"
request.get_full_path() 请求路径,可能包含查询字符串 "/hello/?print=true"
request.is_secure() 如果通过HTTPS访问,则此方法返回True, 否则返回False True 或者 False

      在view函数里,如果想使用URL,请始终用这个属性或方法来得到URL,而不要手动输入。 这会使得代码更加灵活,以便在其它地方重用。 下面是一个简单的例子:

# BAD!
def current_url_view_bad(request):
    return HttpResponse("Welcome to the page at /current/")

# GOOD
def current_url_view_good(request):
    return HttpResponse("Welcome to the page at %s" % request.path)

2. 提交的数据信息

       除了基本的元数据,HttpRequest对象还有两个属性包含了用户所提交的信息: request.GET 和 request.POST。二者都是类字典对象,你可以通过它们来访问GET和POST数据。

1.类字典对象

       我们说request.GET和request.POST是类字典对象,意思是他们的行为像Python里标准的字典对象,但在技术底层上他们不是标准字典对象。 比如说,request.GET和request.POST都有get()、keys()和values()方法,你可以用用 for key in request.GET 获取所有的键。

       POST数据是来自HTML中的〈form〉标签提交的,而GET数据可能来自〈form〉提交也可能是URL中的查询字符串(the query string)。

一个简单的表单处理示例 ,我们现在来创建一个简单的view函数以便让用户可以通过书名从数据库中查找博客。


     (接着这个做吧,http://download.csdn.net/detail/a359680405/8401353


       通常,表单开发分为两个部分: 前端HTML页面用户接口和后台view函数对所提交数据的处理过程。

       第一部分很简单,现在我们来建立个view来显示一个搜索表单:

from django.shortcuts import render_to_response

def search_form(request):
    return render_to_response('search_form.html')
       咱们将它放在 blog\views.py 里。

       search_form.html 模板

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

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

from django.conf.urls import patterns, include, url

urlpatterns = patterns('',
    # ...
    url(r'^search-form/$', 'blog.views.search_form'),
    # ...
)
        现在,如果你运行 runserver 命令,然后访问 http://127.0.0.1:8000/blog/search-form/,你会看到搜索界面。 非常简单。

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

blog\urls.py

urlpatterns = patterns('',
    # ...
    url(r'^search-form/$', 'blog.views.search_form'),
    url(r'^search/$', 'blog.views.search'),
    # ...
)
blog\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)
        在HTML里我们定义了一个变量q。当提交表单时,变量q的值通过 GET(method=”get”) 附加在URL /search/上。处理/search/(search())的视图通过request.GET来获取q的值。

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

2.查询字符串参数

        获取使用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.blog.models import BlogPost

def search(request):
    if 'q' in request.GET and request.GET['q']:
        q = request.GET['q']
        blog= BlogPost.objects.filter(title__icontains=q)
        return render_to_response('search_results.html',{'blog': blog, 'query': q})
    else:
        return HttpResponse('Please submit a search term.')
        让我们来分析一下上面的代码:

        除了检查q是否存在于request.GET之外,我们还检查来request.GET[‘q’]的值是否为空。

        我们使用BlogPost.objects.filter(title__icontains=q)获取数据库中标题包含q的博客。 icontains是一个查询关键字。这个语句可以理解为获取标题里包含q的博客,不区分大小写。

        这是实现博客查询的一个很简单的方法。 不推荐在一个包含大量产品的数据库中使用icontains查询,因为那会很慢。 

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

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

{%
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值