首页 > 代码库 > Python+Django+SAE系列教程11-----request/pose/get/表单
Python+Django+SAE系列教程11-----request/pose/get/表单
表单request,post,get
首先我们来看看Request对象,在这个对象中包含了一些有用的信息,学过B/S开发的人来说这并不陌生,我们来看看在Django中是如何实现的:
属性/方法 | 说明 | 举例 |
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 |
我们可以用一下方法调用即可:
# GOOD def current_url_view_good(request): return HttpResponse("Welcome to the page at %s" % request.path)
除此之外在request.META对象中还包括了一下信息
HTTP_REFERER,进站前链接网页,如果有的话。 (请注意,它是REFERRER的笔误。)
HTTP_USER_AGENT,用户浏览器的user-agent字符串,如果有的话。 例如:"Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17" .
REMOTE_ADDR 客户端IP,如:"12.345.67.89" 。(如果申请是经过代理服务器的话,那么它可能是以逗号分割的多个IP地址,如:"12.345.67.89,23.456.78.90" 。)
用一下方法调用:
# GOOD (VERSION 1) def ua_display_good1(request): try: ua = request.META[‘HTTP_USER_AGENT‘] except KeyError: ua = ‘unknown‘ return HttpResponse("Your browser is %s" % ua) # GOOD (VERSION 2) def ua_display_good2(request): ua = request.META.get(‘HTTP_USER_AGENT‘, ‘unknown‘) return HttpResponse("Your browser is %s" % ua)
下面我们来用以前的例子做一个实验,修改我们之前的view.py文件,加入以下视图:
def request_test(request): GetPath=request.path GetHost=request.get_host() GetFullPath=request.get_full_path() GetIsSecure=request.is_secure() try: GetHTTP_REFERER = request.META[‘HTTP_REFERER‘] except KeyError: GetHTTP_REFERER = ‘unknown‘ try: GetHTTP_USER_AGENT = request.META[‘HTTP_USER_AGENT‘] except KeyError: GetHTTP_USER_AGENT = ‘unknown‘ try: GetREMOTE_ADDR = request.META[‘REMOTE_ADDR‘] except KeyError: GetREMOTE_ADDR = ‘unknown‘ return render_to_response(‘request_test.html‘, locals())
然后,我们在制作一个模板,在template文件夹下,添加一个request_test.html文件:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <title>request对象中的内容</title> </head> <body> <table border="1" cellpadding="10"> <tr><td align="center">标题</td><td align="center">内容</td></tr> <tr><td align="right">Path:</td><td>{{ GetPath }}</td></tr> <tr><td align="right">Host:</td><td>{{ GetHost }}</td></tr> <tr><td align="right">FullPath:</td><td>{{ GetFullPath }}</td></tr> <tr><td align="right">IsSecure:</td><td>{{ GetIsSecure }}</td></tr> <tr><td align="right">HTTP_REFERER:</td><td>{{ GetHTTP_REFERER }}</td></tr> <tr><td align="right">HTTP_USER_AGENT:</td><td>{{ GetHTTP_USER_AGENT }}</td></tr> <tr><td align="right">REMOTE_ADDR:</td><td>{{ GetREMOTE_ADDR }}</td></tr> </table> </body> </html>
修改urls.py文件
from django.conf.urls import patterns, include, url # Uncomment the next two lines to enable the admin: # from django.contrib import admin # admin.autodiscover() urlpatterns = patterns(‘‘, # Examples: # url(r‘^$‘, ‘Bidding.views.home‘, name=‘home‘), # url(r‘^Bidding/‘, include(‘Bidding.foo.urls‘)), # Uncomment the admin/doc line below to enable admin documentation: # url(r‘^admin/doc/‘, include(‘django.contrib.admindocs.urls‘)), # Uncomment the next line to enable the admin: # url(r‘^admin/‘, include(admin.site.urls)), url(r‘^hello/$‘, ‘Bidding.views.hello‘), url(r‘^time/$‘, ‘Bidding.views.current_datetime‘), url(r‘^time/plus/(\d{1,2})/$‘, ‘Bidding.views.hours_ahead‘), url(r‘^hello_base/$‘, ‘Bidding.views.hello_base‘), url(r‘^request_test/$‘, ‘Bidding.views.request_test‘), )
我们在浏览其中输入新的显示视图的路径:http://sunny090302.sinaapp.com/request_test/
就会看到一下的界面了,这里列出的就是整个request对象中的信息了:
除了基本的元数据,HttpRequest对象还有两个属性包含了用户所提交的信息: request.GET 和 request.POST。二者都是类字典对象,你可以通过它们来访问GET和POST数据。POST数据是来自HTML中的〈form〉标签提交的,而GET数据可能来自〈form〉提交也可能是URL中的查询字符串(the query string)。
了解了以上内容后,我们就可以制作一个简单的表单了,通常,表单开发分为两个部分: 前端HTML页面用户接口和后台view函数对所提交数据的处理过程。 第一部分很简单;现在我们来建立个view来显示一个搜索表单(其实就是一个空的函数,返回到一个表单的静态页):
def search_form(request): return render_to_response(‘search_form.html‘)
在第三章已经学过,这个view函数可以放到Python的搜索路径的任何位置。 为了便于讨论,咱们将它放在 Users/views.py 里。从字面上理解,我们这就是要做一个关于用户信息的模块了。Users/views.py文件如下:
# -*- coding: utf-8 -*- from django.shortcuts import render_to_response def search_form(request): return render_to_response(‘Users/search_form.html‘)
然后是这个 search_form.html 模板,之前我们讨论过模板也可以有结构的存放文件,这里为了更加清晰目录结构,我们决定把此模板文件放入template/Users文件夹:
<html> <head> <title>查询用户</title> </head> <body> <form action="/search/" method="get"> 请再此输入用户姓名: <input type="text" name="q"> <input type="submit" value=http://www.mamicode.com/"查找">>而 urls.py 中的 URLpattern 可能是这样的:
from django.conf.urls import patterns, include, url # Uncomment the next two lines to enable the admin: # from django.contrib import admin # admin.autodiscover() urlpatterns = patterns(‘‘, # Examples: # url(r‘^$‘, ‘Bidding.views.home‘, name=‘home‘), # url(r‘^Bidding/‘, include(‘Bidding.foo.urls‘)), # Uncomment the admin/doc line below to enable admin documentation: # url(r‘^admin/doc/‘, include(‘django.contrib.admindocs.urls‘)), # Uncomment the next line to enable the admin: # url(r‘^admin/‘, include(admin.site.urls)), url(r‘^hello/$‘, ‘Bidding.views.hello‘), url(r‘^time/$‘, ‘Bidding.views.current_datetime‘), url(r‘^time/plus/(\d{1,2})/$‘, ‘Bidding.views.hours_ahead‘), url(r‘^hello_base/$‘, ‘Bidding.views.hello_base‘), url(r‘^request_test/$‘, ‘Bidding.views.request_test‘), url(r‘^UsersSearch/$‘, ‘Bidding.Users.views.search_form‘), )我们把文件上传到sae后看效果会发现一个错误,这时因为我们少了一个__init__.py文件,他因该建立在Users\views.py文件的同一级,虽然的的内容是空的,我们以后会介绍这个文件的作用。
这里我们建立一个空的__init__.py,在Users目录中然后上传,就会看到一下的结果了:
当你通过这个form提交数据时,你会得到一个Django 404错误。 这个Form指向的URL /search/ 还没有被实现。 让我们添加第二个视图函数并设置URL:
urls.py:
url(r‘^search/$‘, ‘Bidding.Users.views.search‘),# Users/views.py
# -*- coding: utf-8 -*- from django.http import HttpResponse from django.shortcuts import render_to_response def search_form(request): return render_to_response(‘Users/search_form.html‘) def search(request): if ‘q‘ in request.GET: message = ‘您搜索的关键字是: %r‘ % request.GET[‘q‘] else: message = ‘请输入您要检索的内容‘ return HttpResponse(message)暂时先只显示用户搜索的字词,以确定搜索数据被正确地提交给了Django,这样你就会知道搜索数据是如何在这个系统中传递的。 简而言之:
在HTML里我们定义了一个变量q。当提交表单时,变量q的值通过GET(method=”get”)附加在URL /search/上。处理/search/(search())的视图通过request.GET来获取q的值。需要注意的是在这里明确地判断q是否包含在request.GET中。就像上面request.META小节里面提到,对于用户提交过来的数据,甚至是正确的数据,都需要进行过滤。 在这里若没有进行检测,那么用户提交一个空的表单将引发KeyError异常。
因为使用GET方法的数据是通过查询字符串的方式传递的(例如/search/?q=django),所以我们可以使用requet.GET来获取这些数据。 第三章介绍Django的URLconf系统时我们比较了Django的简洁的URL与PHP/Java传统的URL,我们提到将在第七章讲述如何使用传统的URL。通过刚才的介绍,我们知道在视图里可以使用request.GET来获取传统URL里的查询字符串(例如hours=3)。
获取使用POST方法的数据与GET的相似,只是使用request.POST代替了request.GET。那么,POST与GET之间有什么不同?当我们提交表单仅仅需要获取数据时就可以用GET; 而当我们提交表单时需要更改服务器数据的状态,或者说发送e-mail,或者其他不仅仅是获取并显示数据的时候就使用POST。
接下来,我们发现上面的表单还有一下几个问题:
1、如果我们输出的结果页面是静态的而非模板,这个我想您一定会自己修改,但是不要着急后面还有更简便的方法。
2、如果我们忘记输入关键字点击搜索虽然提示了相应的信息,但是我们还要点击退回按钮,进行再次搜索,最好能在本页面中显示。
3、在模板页面中,我们暴露了提交的视图“search”,这时在实际应用中是危险的。我们需要经过设置隐藏他。
下面我们就来修改表单:
search_form.html:
<html> <head> <title>查询用户</title> </head> <body> {% if error %} <p style="color: red;">请输入您要检索的内容</p> {% endif %} <form action="" method="get"> 请再此输入用户姓名: <input type="text" name="q"> <input type="submit" value=http://www.mamicode.com/"查找">>search_results.html:
<html> <head> <title>查询用户结果页</title> </head> <body> <table border="1" cellpadding="5"><tr><td>一下是您查询的结果</td></tr> <tr> <td>查询条件为:包含"{{query}}"的人员信息</td> </tr> </table> </body> </html>Users/views.py:
# -*- coding: utf-8 -*- from django.http import HttpResponse from django.shortcuts import render_to_response def search_form(request): return render_to_response(‘Users/search_form.html‘) def search1(request): if ‘q‘ in request.GET: message = ‘您搜索的关键字是: %r‘ % request.GET[‘q‘] else: message = ‘请输入您要检索的内容‘ return HttpResponse(message) def search(request): if ‘q‘ in request.GET and request.GET[‘q‘]: q = request.GET[‘q‘] return render_to_response(‘Users/search_results.html‘, {‘query‘: q}) else: return render_to_response(‘Users/search_form.html‘, {‘error‘: True})我们把代码上传,打开浏览器输入search的地址,就可以看到相应的内容了。http://sunny090302.sinaapp.com/search
如果大家有兴许可以再看看http://djangobook.py3k.cn/2.0/chapter07/对form类的介绍,因为在我工作的环境,一般这些都是交给美工做的,并且里面会用到很多图片,form类的两个作用一是可以根据字段自动输出html的表单,二就是验证;第一种情况,一般交给美工,验证我们还是推荐使用js处理,这样避免数据的回发。所以在此就不做介绍了。