表单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 clientIP,如:"12.345.67.89" 。(假设申请是经过代理server的话,那么它可能是以逗号切割的多个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函数对所提交数据的处理过程。 第一部分非常easy;如今我们来建立个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="查找"> </form> </body> </html>
而 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文件,他因该建立在Usersviews.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 = '您搜索的keyword是: %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; 而当我们提交表单时须要更改server数据的状态,或者说发送e-mail,或者其它不不过获取并显示数据的时候就使用POST。
接下来,我们发现上面的表单另一下几个问题:
1、假设我们输出的结果页面是静态的而非模板,这个我想您一定会自己改动,可是不要着急后面还有更简便的方法。
2、假设我们忘记输入keyword点击搜索尽管提示了对应的信息,可是我们还要点击退回button,进行再次搜索,最好能在本页面中显示。
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="查找"> </form> </body> </html>
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 = '您搜索的keyword是: %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处理,这样避免数据的回发。所以在此就不做介绍了。