首页 > 代码库 > Python+Django+SAE系列教程11-----request/pose/get/表单

Python+Django+SAE系列教程11-----request/pose/get/表单

表单requestpostget

首先我们来看看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处理,这样避免数据的回发。所以在此就不做介绍了。