Django uses request and response objects to pass state through the system.
Django使用request和response对象在系统间传递状态。
When a page is requested, Django creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function. Each view is responsible for returning an HttpResponse object.
当一个页面被请示时,Django创建一个包含请求元数据的 HttpRequest 对象。 然后Django调入合适的视图,把 HttpRequest 作为视图函数的第一个参数 传入。每个视图要负责返回一个 HttpResponse 对象。
Weve used these objects often throughout the book; this appendix explains the complete APIs for HttpRequest and HttpResponse objects.
我们在书中已经使用过这些对象了;这篇附录说明了 HttpRequest 和 HttpResponse 的全部API。
HttpRequest represents a single HTTP request from some user-agent.
HttpRequest 表示来自某客户端的一个单独的HTTP请求。
Much of the important information about the request is available as attributes on the HttpRequest instance (see Table H-1). All attributes except session should be considered read-only.
HttpRequest实例的属性包含了关于此次请求的大多数重要信息(详见表H-1)。 除了session外的所有属性都应该认为是只读的.
Attribute | Description |
---|---|
path | A string representing the full path to the requested page, not including the domain for example, "/music/bands/the_beatles/" . |
method | A string representing the HTTP method used in the request. This is guaranteed to be uppercase. For example: if request.method == 'GET': do_something() elif request.method == 'POST': do_something_else() |
GET | A dictionary-like object containing all given HTTP GET parameters. See the upcoming QueryDict documentation. |
POST | A dictionary-like object containing all given HTTP POST parameters. See the upcoming QueryDict documentation. Its possible that a request can come in via POST with an empty POST dictionary if, say, a form is requested via the POST HTTP method but does not include form data. Therefore, you shouldnt use if request.POST to check for use of the POST method; instead, use if request.method == "POST" (see the method entry in this table). Note: POST does not include file-upload information. See FILES . |
REQUEST | For convenience, a dictionary-like object that searches POST first, and then GET . Inspired by PHPs $_REQUEST . For example, if GET = {"name": "john"} and POST = {"age": '34'} , REQUEST["name"] would be "john" , and REQUEST["age"] would be "34" . Its strongly suggested that you use GET and POST instead of REQUEST , because the former are more explicit. |
COOKIES | A standard Python dictionary containing all cookies. Keys and values are strings. See Chapter 12 for more on using cookies. |
FILES | A dictionary-like object containing all uploaded files. Each key in FILES is the name from the <input type="file" name="" /> . Each value in FILES is a standard Python dictionary with the following three keys:
Note that FILES will contain data only if the request method was POST and the <form> that posted to the request had enctype="multipart/form-data" . Otherwise, FILES will be a blank dictionary-like object. |
META | A standard Python dictionary containing all available HTTP headers. Available headers depend on the client and server, but here are some examples:
Any HTTP headers are available in META as keys prefixed with HTTP_ , for example:
|
user | A django.contrib.auth.models.User object representing the currently logged-in user. If the user isnt currently logged in, user will be set to an instance of django.contrib.auth.models.AnonymousUser . You can tell them apart with is_authenticated() , like so: if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users. user is available only if your Django installation has the AuthenticationMiddleware activated. For the complete details of authentication and users, see Chapter 12. |
session | A readable and writable, dictionary-like object that represents the current session. This is available only if your Django installation has session support activated. See Chapter 12. |
raw_post_data | The raw HTTP POST data. This is useful for advanced processing. |
属性 | 描述 |
---|---|
path | 表示提交请求页面完整地址的字符串, 不包括域名,如 "/music/bands/the_beatles/" 。 |
method | 表示提交请求使用的HTTP方法。 它总是大写的。例如: if request.method == 'GET': do_something() elif request.method == 'POST': do_something_else() |
GET | 一个类字典对象,包含所有的HTTP的GET参数的信息。 见 QueryDict 文档。 |
POST | 一个类字典对象,包含所有的HTTP的POST参数的信息。 见 QueryDict 文档。 通过POST提交的请求有可能包含一个空的 POST 字典, 也就是说, 一个通过POST方法提交的表单可能不包含数据。 因此,不应该使用 if request.POST 来判断POST方法的使用, 而是使用 if request.method == "POST" (见表中的 method 条目)。 注意: POST 并 不 包含文件上传信息。 见 FILES 。 |
REQUEST | 为了方便而创建,这是一个类字典对象,先搜索 POST , 再搜索 GET 。 灵感来自于PHP的 $_REQEUST 。 例如, 若 GET = {"name": "john"} , POST = {"age": '34'} , REQUEST["name"] 会是 "john" , REQUEST["age"] 会是 "34" 。 强烈建议使用 GET 和 POST ,而不是 REQUEST 。 这是为了向前兼容和更清楚的表示。 |
COOKIES | 一个标准的Python字典,包含所有cookie。 键和值都是字符串。cookie使用的更多信息见第12章。 |
FILES | 一个类字典对象,包含所有上传的文件。 FILES 的键来自 <input type="file" name="" /> 中的 name 。 FILES 的值是一个标准的Python字典, 包含以下三个键:
注意 FILES 只在请求的方法是 POST ,并且提交的 <form> 包含 enctype="multipart/form-data" 时 才包含数据。否则, FILES 只是一个空的类字典对象。 |
META | 一个标准的Python字典,包含所有有效的HTTP头信息。 有效的头信息与客户端和服务器有关。 这里有几个例子:
在 META 中有效的任一HTTP头信息都是带有 HTTP_ 前缀的 键,例如:
|
user | 一个 django.contrib.auth.models.User 对象表示 当前登录用户。 若当前用户尚未登录, user 会设为 django.contrib.auth.models.AnonymousUser 的一个实例。 可以将它们与 is_authenticated() 区别开: if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users. user 仅当Django激活 AuthenticationMiddleware 时有效。 关于认证和用户的完整细节,见第12章。 |
session | 一个可读写的类字典对象,表示当前session。 仅当Django已激活session支持时有效。 见第12章。 |
raw_post_data | POST的原始数据。 用于对数据的复杂处理。 |
Request objects also have a few useful methods, as shown in Table H-2.
Request对象同样包含了一些有用的方法,见表H-2。
Method | Description |
---|---|
__getitem__(key) | Returns the GET/POST value for the given key, checking POST first, and then GET. Raises KeyError if the key doesnt exist. This lets you use dictionary-accessing syntax on an HttpRequest instance. For example, request["foo"] is the same as checking request.POST["foo"] and then request.GET["foo"] . |
has_key() | Returns True or False , designating whether request.GET or request.POST has the given key. |
get_full_path() | Returns the path , plus an appended query string, if applicable. For example, "/music/bands/the_beatles/?print=true" |
is_secure() | Returns True if the request is secure; that is, if it was made with HTTPS. |
方法 | 描述 |
---|---|
__getitem__(key) | 请求所给键的GET/POST值,先查找POST,然后是GET。 若键不存在,则引发异常 KeyError 。 该方法使用户可以以访问字典的方式来访问一个 HttpRequest 实例。 例如, request["foo"] 和先检查 request.POST["foo"] 再检查 request.GET["foo"] 一 样。 |
has_key() | 返回 True 或 False , 标识 request.GET 或 request.POST 是否包含所给的 键。 |
get_full_path() | 返回 path ,若请求字符串有效,则附加于其后。 例如, "/music/bands/the_beatles/?print=true" 。 |
is_secure() | 如果请求是安全的,则返回 True 。 也就是说,请求是以HTTPS的形式提交的。 |
In an HttpRequest object, the GET and POST attributes are instances of django.http.QueryDict . QueryDict is a dictionary-like class customized to deal with multiple values for the same key. This is necessary because some HTML form elements, notably <select multiple="multiple"> , pass multiple values for the same key.
在一个 HttpRequest 对象中, GET 和 POST 属性都是 django.http.QueryDict 的实例。 QueryDict 是一个类似于字典的类,专门用来处理用一个键的多值。当处理一些HTML表单中的元素,特别是 <select multiple="multiple"> 之类传递同一key的多值的元素时,就需要这个类了。
QueryDict instances are immutable, unless you create a copy() of them. That means you cant change attributes of request.POST and request.GET directly.
QueryDict 实例是不可变的,除非创建了一个 copy() 副本。也就是说不能直接更改 request.POST 和 request.GET 的属性。
QueryDict implements the all standard dictionary methods, because its a subclass of dictionary. Exceptions are outlined in Table H-3.
QueryDict 实现了所有标准的字典的方法,因为它正是字典的一个子类。与其不同的东西都已在表H-3中列出。
Method | Differences from Standard dict Implementation |
---|---|
__getitem__ | Works just like a dictionary. However, if the key has more than one value, __getitem__() returns the last value. |
__setitem__ | Sets the given key to [value] (a Python list whose single element is value ). Note that this, as other dictionary functions that have side effects, can be called only on a mutable QueryDict (one that was created via copy() ). |
get() | If the key has more than one value, get() returns the last value just like __getitem__ . |
update() | Takes either a QueryDict or standard dictionary. Unlike the standard dictionarys update method, this method appends to the current dictionary items rather than replacing them: >>> q = QueryDict('a=1') >>> q = q.copy() # to make it mutable >>> q.update({'a': '2'}) >>> q.getlist('a') ['1', '2'] >>> q['a'] # returns the last ['2'] |
items() | Just like the standard dictionary items() method, except this uses the same last-value logic as __getitem()__ : >>> q = QueryDict('a=1&a=2&a=3') >>> q.items() [('a', '3')] |
values() | Just like the standard dictionary values() method, except this uses the same last-value logic as __getitem()__ . |
方法 | 与标准字典实现的不同 |
---|---|
__getitem__ | 与一个字典一样。但是,当一个键有多个值时, __getitem__() 返回最后一个值。 |
__setitem__ | 将所给键的值设为 [value] (一个只有一个 value 元素的 Python列表)。 注意,因对其它的字典函数有副作用,故它只能被称 为一个可变的 QueryDict (通过 copy() 创建)。 |
get() | 如果一个键多个值,和 __getitem__ 一样, get() 返回 最后一个值。 |
update() |
>>> q = QueryDict('a=1') >>> q = q.copy() # 使其可变 >>> q.update({'a': '2'}) >>> q.getlist('a') ['1', '2'] >>> q['a'] # 返回最后一个值 ['2'] |
items() | 和标准字典的 items() 方法一样, 不同的是它和 __getitem()__ 一样,返回最后一个值: >>> q = QueryDict('a=1&a=2&a=3') >>> q.items() [('a', '3')] |
values() | 和标准字典的 values() 方法一样, 不同的是它和 __getitem()__ 一样,返回最后一个值。 |
In addition, QueryDict has the methods shown in Table H-4.
另外, QueryDict 还有在表H-4中列出的方法。
Method | Description |
---|---|
copy() | Returns a copy of the object, using copy.deepcopy() from the Python standard library. The copy will be mutable that is, you can change its values. |
getlist(key) | Returns the data with the requested key, as a Python list. Returns an empty list if the key doesnt exist. Its guaranteed to return a list of some sort. |
setlist(key, list_) | Sets the given key to list_ (unlike __setitem__() ). |
appendlist(key, item) | Appends an item to the internal list associated with key . |
setlistdefault(key, l) | Just like setdefault , except it takes a list of values instead of a single value. |
lists() | Like items() , except it includes all values, as a list, for each member of the dictionary. For example: >>> q = QueryDict('a=1&a=2&a=3') >>> q.lists() [('a', ['1', '2', '3'])] |
urlencode() | Returns a string of the data in query-string format (e.g., "a=2&b=3&b=5" ). |
方法 | 描述 |
---|---|
copy() | 返回一个对象的副本,使用的是Python标准库中的 copy.deepcopy() 。 该副本是可变的, 也就是说,你能改变它的值。 |
getlist(key) | 以Python列表的形式返回所请求键的数据。 若键不存在则返回空列表。 它保证了一定会返回某种形式的list。 |
setlist(key, list_) | 将所给键的键值设为 list_ (与 __setitem__() 不同)。 |
appendlist(key, item) | 在 key 相关的list上增加 item 。 |
setlistdefault(key, l) | 和 setdefault 一样, 不同的是它的第二个参数是 一个列表,而不是一个值。 |
lists() | 和 items() 一样, 不同的是它以一个列表的形式 返回字典每一个成员的所有值。 例如: >>> q = QueryDict('a=1&a=2&a=3') >>> q.lists() [('a', ['1', '2', '3'])] |
urlencode() | 返回一个请求字符串格式的数据字符串 (如, "a=2&b=3&b=5" )。 |
For example, given this HTML form:
例如, 给定这个HTML表单:
<form action="/foo/bar/" method="post"> <input type="text" name="your_name" /> <select multiple="multiple" name="bands"> <option value="beatles">The Beatles</option> <option value="who">The Who</option> <option value="zombies">The Zombies</option> </select> <input type="submit" /> </form>
if the user enters "John Smith" in the your_name field and selects both The Beatles and The Zombies in the multiple select box, heres what Djangos request object would have:
如果用户在 your_name 中输入 "John Smith" ,并且在多选框中同时选择了The Beatles和The Zombies,那么以下就是Django的request对象所拥有的:
>>> request.GET {} >>> request.POST {'your_name': ['John Smith'], 'bands': ['beatles', 'zombies']} >>> request.POST['your_name'] 'John Smith' >>> request.POST['bands'] 'zombies' >>> request.POST.getlist('bands') ['beatles', 'zombies'] >>> request.POST.get('your_name', 'Adrian') 'John Smith' >>> request.POST.get('nonexistent_field', 'Nowhere Man') 'Nowhere Man'
Implementation Note:
使用时请注意:
The GET , POST , COOKIES , FILES , META , REQUEST , raw_post_data , and user attributes are all lazily loaded. That means Django doesnt spend resources calculating the values of those attributes until your code requests them.
GET , POST , COOKIES , FILES , META , REQUEST , raw_post_data 和 user 这些属性都是延迟加载的。 也就是说除非代码中访问它们,否则Django并不会花费资源来计算这些属性值。
In contrast to HttpRequest objects, which are created automatically by Django, HttpResponse objects are your responsibility. Each view you write is responsible for instantiating, populating, and returning an HttpResponse .
与Django自动创建的 HttpRequest 对象相比, HttpResponse 对象则是由你创建的。 你创建的每个视图都需要实例化,处理和返回一个 HttpResponse 对象。
The HttpResponse class lives at django.http.HttpResponse .
HttpResponse 类存在于 django.http.HttpResponse 。
Typically, youll construct an HttpResponse to pass the contents of the page, as a string, to the HttpResponse constructor:
一般情况下,你创建一个 HttpResponse 时,以字符串的形式来传递页面的内容给 HttpResponse 的构造函数:
>>> response = HttpResponse("Here's the text of the Web page.") >>> response = HttpResponse("Text only, please.", mimetype="text/plain")
But if you want to add content incrementally, you can use response as a filelike object:
但是如果希望逐渐增加内容,则可以把 response 当作一个类文件对象使用:
>>> response = HttpResponse() >>> response.write("<p>Here's the text of the Web page.</p>") >>> response.write("<p>Here's another paragraph.</p>")
You can pass HttpResponse an iterator rather than passing it hard-coded strings. If you use this technique, follow these guidelines:
你可以将一个迭代器传递给 HttpResponse ,而不是固定的字符串。如果你要这样做的话,请遵循以下规则:
The iterator should return strings.
迭代器应返回字符串。
If an HttpResponse has been initialized with an iterator as its content, you cant use the HttpResponse instance as a filelike object. Doing so will raise Exception .
若一个 HttpResponse 已经通过实例化,并以一个迭代器作为其内容,就不能以一个类文件对象使用 HttpResponse 实例。这样做的话,会导致一个 Exception 。
Finally, note that HttpResponse implements a write() method, which makes is suitable for use anywhere that Python expects a filelike object. See Chapter 11 for some examples of using this technique.
最后,注意 HttpResponse 实现了一个 write() 方法,使其可以在任何可以使用类文件对象的地方使用。 这方面的例子见第11章。
You can add and delete headers using dictionary syntax:
您可以使用字典一样地添加和删除头信息。
>>> response = HttpResponse() >>> response['X-DJANGO'] = "It's the best." >>> del response['X-PHP'] >>> response['X-DJANGO'] "It's the best."
You can also use has_header(header) to check for the existence of a header.
你也可以使用 has_header(header) 来检查一个头信息项是否存在。
Avoid setting Cookie headers by hand; instead, see Chapter 12 for instructions on how cookies work in Django.
请避免手工设置 Cookie 头,参见第12章Django中cookie工作原理的说明。
Django includes a number of HttpResponse subclasses that handle different types of HTTP responses (see Table H-5). Like HttpResponse , these subclasses live in django.http .
Django包含许多处理不同类型的HTTP请求的 HttpResponse 子类(见表H-5)。像 HttpResponse 一样,这些类在 django.http 中。
Class | Description |
---|---|
HttpResponseRedirect | The constructor takes a single argument: the path to redirect to. This can be a fully qualified URL (e.g., 'http://search.yahoo.com/' ) or an absolute URL with no domain (e.g., '/search/' ). Note that this returns an HTTP status code 302. |
HttpResponsePermanentRedirect | Like HttpResponseRedirect , but it returns a permanent redirect (HTTP status code 301) instead of a found redirect (status code 302). |
HttpResponseNotModified | The constructor doesnt take any arguments. Use this to designate that a page hasnt been modified since the users last request. |
HttpResponseBadRequest | Acts just like HttpResponse but uses a 400 status code. |
HttpResponseNotFound | Acts just like HttpResponse but uses a 404 status code. |
HttpResponseForbidden | Acts just like HttpResponse but uses a 403 status code. |
HttpResponseNotAllowed | Like HttpResponse , but uses a 405 status code. It takes a single, required argument: a list of permitted methods (e.g., ['GET', 'POST'] ). |
HttpResponseGone | Acts just like HttpResponse but uses a 410 status code. |
HttpResponseServerError | Acts just like HttpResponse but uses a 500 status code. |
You can, of course, define your own HttpResponse subclass to support different types of responses not supported out of the box.
当然,如果框架不支持一些特性,你也可以定义自己的 HttpResponse 子类来处理不同的请求。
Returning HTTP error codes in Django is easy. Weve already mentioned the HttpResponseNotFound , HttpResponseForbidden , HttpResponseServerError , and other subclasses. Just return an instance of one of those subclasses instead of a normal HttpResponse in order to signify an error, for example:
在Django中返回HTTP错误代码很容易。我们前面已经提到 HttpResponseNotFound , HttpResponseForbidden , HttpResponseServerError ,和其它子类。为了更好地表示一个错误,只要返回这些子类之一的一个实例,而不是一个通常的 HttpResponse ,例如:
def my_view(request): # ... if foo: return HttpResponseNotFound('<h1>Page not found</h1>') else: return HttpResponse('<h1>Page was found</h1>')
Because a 404 error is by far the most common HTTP error, theres an easier way to handle it.
至今为止,404错误是最常见的HTTP错误,有一种更容易的方式来处理。
When you return an error such as HttpResponseNotFound , youre responsible for defining the HTML of the resulting error page:
当返回一个错误,比如 HttpResponseNotFound 时,需要定义错误页面的HTML:
return HttpResponseNotFound('<h1>Page not found</h1>')
For convenience, and because its a good idea to have a consistent 404 error page across your site, Django provides an Http404 exception. If you raise Http404 at any point in a view function, Django will catch it and return the standard error page for your application, along with an HTTP error code 404.
为了方便,而且定义一个通用的应用于网站的404错误页面也是一个很好的选择,Django提供了一个 Http404 异常。如果在视图的任何地方引发 Http404 异常,Django就会捕获错误并返回应用程序的标准错误页面,当然,还有HTTP错误代码404。
Heres an example:
例如:
from django.http import Http404 def detail(request, poll_id): try: p = Poll.objects.get(pk=poll_id) except Poll.DoesNotExist: raise Http404 return render_to_response('polls/detail.html', {'poll': p})
In order to use the Http404 exception to its fullest, you should create a template that is displayed when a 404 error is raised. This template should be called 404.html , and it should be located in the top level of your template tree.
为了完全发挥出 Http404 的功能,应创建一个模板,在404错误被引发时显示。模板的名字应该是 404.html ,而且应该位于模板树的最高层。
When you raise an Http404 exception, Django loads a special view devoted to handling 404 errors. By default, its the view django.views.defaults.page_not_found , which loads and renders the template 404.html .
当引发 Http404 异常,Django加载一个专门处理404错误的视图。默认情况下,这个视图是 django.views.defaults.page_not_found ,它会加载并显示模板 404.html 。
This means you need to define a 404.html template in your root template directory. This template will be used for all 404 errors.
这意味着需要在根模板目录定义一个 404.html 模板。这个模板会作用于所有404错误。
This page_not_found view should suffice for 99% of Web applications, but if you want to override the 404 view, you can specify handler404 in your URLconf, like so:
视图 page_not_found 适用于99%的网站应用程序,但若是希望重载该视图,可以在URLconf中指定 handler404 ,就像这样:sfas
from django.conf.urls.defaults import * urlpatterns = patterns('', ... ) handler404 = 'mysite.views.my_custom_404_view'
Behind the scenes, Django determines the 404 view by looking for handler404 . By default, URLconfs contain the following line:
后台执行时,Django以 handler404 来确定404视图。默认情况下,URLconf包含以下内容:
from django.conf.urls.defaults import *
That takes care of setting handler404 in the current module. As you can see in django/conf/urls/defaults.py , handler404 is set to 'django.views.defaults.page_not_found' by default.
这句话负责当前模块中的 handler404 设置。正如你所见,在 django/conf/urls/defaults.py 中, handler404 默认被设为 'django.views.defaults.page_not_found' 。
There are three things to note about 404 views:
关于404视图,有三点需要注意:
The 404 view is also called if Django doesnt find a match after checking every regular expression in the URLconf.
当Django在URLconf无法找到匹配的正则表达式时,404视图会显示。
If you dont define your own 404 view and simply use the default, which is recommended you still have one obligation: to create a 404.html template in the root of your template directory. The default 404 view will use that template for all 404 errors.
如果没有定义自己的404视图,而只是简单地使用默认的视图,此时就需要在模板目录的根目录创建一个 404.html 模板。默认的404视图会对所有404错误使用改模板。
If DEBUG is set to True (in your settings module), then your 404 view will never be used, and the traceback will be displayed instead.
若 DEBUG 被设为 True (在settings模块内),则404视图不会被使用,此时显示的是跟踪信息。
Similarly, Django executes special-case behavior in the case of runtime errors in view code. If a view results in an exception, Django will, by default, call the view django.views.defaults.server_error , which loads and renders the template 500.html .
同样地,若是在试图代码中出现了运行时错误,Django会进行特殊情况处理。如果视图引发了一个异常,Django会默认访问视图 django.views.defaults.server_error ,加载并显示模板 500.html 。
This means you need to define a 500.html template in your root template directory. This template will be used for all server errors.
这意味着需要在根模板目录定义一个 500.html 模板。该模板作用于所有服务器错误。
This server_error view should suffice for 99% of Web applications, but if you want to override the view, you can specify handler500 in your URLconf, like so:
视图 server_error 适用于99%的网站应用程序,但若是希望重载该视图,可以在URLconf中指定 handler500 ,就像这样:
from django.conf.urls.defaults import * urlpatterns = patterns('', ... ) handler500 = 'mysite.views.my_custom_error_view'
关于本评注系统
本站使用上下文关联的评注系统来收集反馈信息。不同于一般对整章做评注的做法, 我们允许你对每一个独立的“文本块”做评注。一个“文本块”看起来是这样的:
一个“文本块”是一个段落,一个列表项,一段代码,或者其他一小段内容。 你选中它会高亮度显示:
要对文本块做评注,你只需要点击它旁边的标识块:
我们会仔细阅读每个评论,如果可能的话我们也会把评注考虑到未来的版本中去:
如果你愿意你的评注被采用,请确保留下你的全名 (注意不是昵称或简称)
Many, many thanks to Jack Slocum; the inspiration and much of the code for the comment system comes from Jack's blog, and this site couldn't have been built without his wonderful
YAHOO.ext
library. Thanks also to Yahoo for YUI itself.