Django Views: Dynamic Content
世味年来薄似纱,谁令骑马客京华。
小楼一夜听春雨,深巷明朝卖杏花。
矮纸斜行闲作草,晴窗细乳戏分茶。
素衣莫起风尘叹,犹及清明可到家。
Your Second View: Dynamic Content(你的第二个视图:动态内容)
Our “Hello world” view was instructive in demonstrating the basics of how Django works, but it wasn’t an example of a dynamic Web page, because the content of the page is always the same. Every time you view /hello/
, you’ll see the same thing; it might as well be a static HTML file.(我们的Django视图在演示Django基本工作的时候比较有优势,但是他不是一个动态网页的例子,因为网页内容总是相同的,每次你看/hello/的时候,你都会看到相同的内容;他也可以说是一个静态HTML文件)
For our second view, let’s create something more dynamic – a Web page that displays the current date and time. This is a nice, simple next step, because it doesn’t involve a database or any user input – just the output of your server’s internal clock. It’s only marginally more exciting than “Hello world,” but it’ll demonstrate a few new concepts. This view needs to do two things: calculate the current date and time, and return an HttpResponse
containing that value. If you have experience with Python, you know that Python includes a datetime
module for calculating dates. Here’s how to use it:(为了我们的第二个视图,我们会创建更多的动态内容---一个显示当前日期和时间的Web网页。下面的很精彩也很简单哦,他不涉及数据库或者任何的用户输入,仅仅只是输出你的服务器的内部时钟,他只比简单的“Hello World”高明了那么一点点,但是他会展示一点点的新概念。做这个视图函数需要两件事情:计算当前的日期和时间,and 返回一个HttpResponse包含前面计算好的数值。如果你以前了解过Python的话,你应该知道Python包含一个叫做datetime的模块他用于计算日期,这里是使用教程)
>>> import datetime
>>> now = datetime.datetime.now()
>>> now
datetime.datetime(2015, 7, 15, 18, 12, 39, 2731)
>>> print (now)
2015-07-15 18:12:39.002731
That’s simple enough, and it has nothing to do with Django. It’s just Python code. (I want to emphasize that you should be aware of what code is “just Python” vs. code that is Django-specific. As you learn Django, I want you to be able to apply your knowledge to other Python projects that don’t necessarily use Django.) To make a Django view that displays the current date and time, we just need to hook this datetime.datetime.now()
statement into a view and return an HttpResponse
. Here’s what the updated views.py
looks like:(这足够简单了,并没有和Django协同工作。这仅仅只是Python 代码(我想强调的是你应该要注意到什么是单纯的Python代码和那些事Django的特有代码。当你学习Django的时候,我想让你能过应用你的只是到其他的Python 工程当中而不是仅仅的用于 Django)为了让Django的视图展现出当前的日期和使劲啊,我们仅仅需要将datetime.datetime.now()
潜入到视图里面and return 一个HttpResponse,这里是更改之后的代码看起来的样子。 )
from django.http import HttpResponse
import datetime def hello(request):
return HttpResponse("Hello world") def current_datetime(request):
now = datetime.datetime.now()
html = "It is now %s." % now
return HttpResponse(html)
Let’s step through the changes we’ve made to views.py
to accommodate the current_datetime
view.(让我们一步步的思考我们对views.py做出的改变来适应current_datetime视图)
- We’ve added an
import datetime
to the top of the module, so we can calculate dates.(我们加入了import datetime
这个模块到顶部,所以我们可以计算时间了。) - The new
current_datetime
function calculates the current date and time, as adatetime.datetime
object, and stores that as the local variablenow
.(我们可以用datetime.datetime
对象去计算current_datetime
视图函数中的日期和时间,并且申请一个新的局部变量) - The second line of code within the view constructs an HTML response using Python’s “format-string”
capability. The%s
within the string is a placeholder, and the percent sign after the string means “Replace the%s
in the preceding string with the value of the variablenow
.” Thenow
variable is technically adatetime.datetime
object, not a string, but the%s
format character converts it to its string representation, which is something like"2015-07-15 18:12:39.002731"
. This will result in an HTML string such as"It is now 2015-07-15 18:12:39.002731."
.(第二行用Python的字符串格式化构造出来一个HTML 响应字符串) - Finally, the view returns an
HttpResponse
object that contains the generated response – just as we did inhello
.(最终,这个视图函数返回HttpResponse对象包含了需要响应的内容---就像我们在hello 那里做的一样)
After adding that to views.py
, add the URLpattern to urls.py
to tell Django which URL should handle this view. Something like /time/
would make sense:(在将这些内容添加到views.py之后,在添加URLpattern到urls.py 告诉Django用那个URL来处理这个视图,用/time/的话是有意义的(便于理解网页的内容是什么))
from django.conf.urls import include, url
from django.contrib import admin
from mysite.views import hello, current_datetime urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^hello/$', hello),
url(r'^time/$', current_datetime),
]
We’ve made two changes here. First, we imported the current_datetime
function at the top. Second, and more importantly, we added a URLpattern mapping the URL /time/
to that new view. Getting the hang of this? With the view written and URLconf updated, fire up the runserver
and visit http://127.0.0.1:8000/time/
in your browser. You should see the current date and time. If you don’t see your local time, it is likely because the default time zone in your settings.py
is set to 'UTC'.(我们在这里做出了两处改变,第一:我们在顶部导入了
current_datetime
函数。第二:也是更重要的,我们添加了/time/到URLpattern。理解了么?随着视图函数的书写和URLconf的更新,重启服务器并且访问http://127.0.0.1:8000/time/
,你应该可以看到当前的日期和时间,如果你看到的不是本地时间,他可能是因为setting.py中设置的默认时区时“UTC”)
URLconfs and Loose Coupling (URL配置和松散耦合)
Now’s a good time to highlight a key philosophy behind URLconfs and behind Django in general: the principle of loose coupling. Simply put, loose coupling is a software-development approach that values the importance of making pieces interchangeable. If two pieces of code are loosely coupled, then changes made to one of the pieces will have little or no effect on the other.(现在时指出Django和URL配置背后的哲学了---松散耦合原则。简单的说,松散耦合是一个重要的保证软件开发块的互换性的方法。 如果两部分代码分别都是松散耦合的,这样的话对其中的一部分进行改变对整体会有极小甚至没有影响。)
Django’s URLconfs are a good example of this principle in practice. In a Django web application, the URL definitions and the view functions they call are loosely coupled; that is, the decision of what the URL should be for a given function, and the implementation of the function itself, reside in two separate places.(在这个原则中Django的URL配置就是一个很好的例子,在Django的 应用当中,URL配置和视图函数就属于松散耦合,就是决定URL返回那个视图函数,和实现函数本身在两个不同的地方。)
For example, consider our current_datetime
view. If we wanted to change the URL for the application – say, to move it from /time/
to /current-time/
– we could make a quick change to the URLconf, without having to worry about the view itself. Similarly, if we wanted to change the view function – altering its logic somehow – we could do that without affecting the URL to which the function is bound. Furthermore, if we wanted to expose the current-date functionality at several URLs, we could easily take care of that by editing the URLconf, without having to touch the view code.(例如,参考一下我们的current_datetime 视图函数,如果我们想要改变这个应用对应的URL,换句话说就是将他从 /time/到 /current_time/,我们可以快速的改变URL配置,而不用担心视图函数。如果我们想改变视图函数改变他的某些逻辑,我们可以在不影响URL的绑定的情况下做到。此外,我们可以修改函数在不影响URL绑定的情况下,我们可以很容易的编辑URL配置,而不去改动视图函数。)
In this example, our current_datetime
is available at two URLs. It’s a contrived example, but this technique can come in handy:(在这个例子里面,我们的current_datetime
绑定了两个URL,这是一个我故意写的例子,但是这种技术以后可以派上用场。)
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^hello/$', hello),
url(r'^time/$', current_datetime),
url(r'^another-time-page/$', current_datetime),
]
URLconfs and views are loose coupling in action. I’ll continue to point out examples of this important philosophy throughout the book.(URL配置和视图函数就是松散耦合,我们将继续指出这一重要哲学在本书中的例子。)
Your Third View: Dynamic URLs(你的第三个视图函数:动态URL)
In our current_datetime
view, the contents of the page – the current date/time – were dynamic, but the URL (/time/
) was static. In most dynamic Web applications though, a URL contains parameters that influence the output of the page. For example, an online bookstore might give each book its own URL, like /books/243/
and /books/81196/
. Let’s create a third view that displays the current date and time offset by a certain number of hours. The goal is to craft a site in such a way that the page /time/plus/1/
displays the date/time one hour into the future, the page /time/plus/2/
displays the date/time two hours into the future, the page /time/plus/3/
displays the date/time three hours into the future, and so on. A novice might think to code a separate view function for each hour offset, which might result in a URLconf like this:(在我们的current_datetime
视图函数里面,这一页的内容date/time 是动态的,但是URL /time/是静态的,不过在大多数的动态网页应用程序中的URL包含可以影响输出页面结果的参数。例如一个在线的书店可能会给每一本书一个URL,就像/book/243/ and /book/81196/ 。让我们创建第三个函数---展现加上时间偏差量之后的当前的日期和时间,目标是设计一个站点就是 /time/plus/1 展现当前时间加上一个小时, /time/plus/2/ 展现当前时间加上两个小时, /time/plus/3展现当前时间加上三个小时 等等。新手可能会认为用不同的视图函数来处理不同的地址。)
urlpatterns = [
url(r'^time/$', current_datetime),
url(r'^time/plus/1/$', one_hour_ahead),
url(r'^time/plus/2/$', two_hours_ahead),
url(r'^time/plus/3/$', three_hours_ahead),
]
Clearly, this line of thought is flawed.(显然,这种想法是有缺陷的)
Not only would this result in redundant view functions, but also the application is fundamentally limited to supporting only the predefined hour ranges – one, two or three hours.(这种方法不仅时有冗余的视图函数,而且从根本上应用也会被限制在预预定义好的时间范围内 - 一,二或三个小时。)
If we decided to create a page that displayed the time four hours into the future, we’d have to create a separate view and URLconf line for that, furthering the duplication.(如果我们想创建一个加四个小时的页面,我们需要创建视图函数和URL配置,这样会更加的重复。)
How, then do we design our application to handle arbitrary hour offsets? The key is to use wildcard URLpatterns. As I mentioned previously, a URLpattern is a regular expression; hence, we can use the regular expression pattern \d+
to match one or more digits:(那么,我们如何设计一个应用去处理任意时间的偏差?关键是用通配符URLpattern。正如我之前注意的,一个URLpattern是一个正则表达式,因此我们可以使用一个正则表达式模式\d+来匹配一个或多个数字。)
urlpatterns = [
# ...
url(r'^time/plus/\d+/$', hours_ahead),
# ...
]
(I’m using the # ...
to imply there might be other URLpatterns that have been trimmed from this example.) This new URLpattern will match any URL such as /time/plus/2/
, /time/plus/25/
, or even /time/plus/100000000000/
. Come to think of it, let’s limit it so that the maximum allowed offset is something reasonable.(我用 # 表示这里可能有其他被隐藏的URLpattern例子,这个新的URLpattern将会匹配任何类似/time/plus/2/ , /time/plus/25/,或者甚至时/time/plus/100000000000
/。 再想一想,让我们将他最大限制到一个合理的数值内)
In this example, we will set a maximum 99 hours by only allowing either one- or two-digit numbers – and in regular expression syntax, that translates into \d{1,2}
:(在这里例子里面,我们会设置一个最大为99小时的例子,只允许一个或者两个数字 - 用正则表达式,他可以翻译成\d{1,2})
url(r'^time/plus/\d{1,2}/$', hours_ahead),
Now that we’ve designated a wildcard for the URL, we need a way of passing that wildcard data to the view function, so that we can use a single view function fgor any arbitrary hour offset. We do this by placing parentheses around the data in the URLpattern that we want to save. In the case of our example, we want to save whatever number was entered in the URL, so let’s put parentheses around the \d{1,2}
,
like this:(既然我们已经设计好了这个URL的通配符,我们需要一个方法去传递这个数据到视图函数里面。现在我们就可以用一个视图函数去处理任意的时间偏差。我们将括号放到URLpattern中我们想保存的数据哪里,在这个例子里面我们想保存输入到URL里面的数值,因此我们把括号放置到\d{1,2}只外。)
url(r'^time/plus/(\d{1,2})/$', hours_ahead),
If you’re familiar with regular expressions, you’ll be right at home here; we’re using parentheses to capture data from the matched text. The final URLconf, including our previous two views, looks like this:(如果你熟悉正则表达式的话,那你就应该知道,我们也是用括号从文本中来提取数据的。最终的URLconf包含了上面的两个试图。)
from django.conf.urls import include, url
from django.contrib import admin
from mysite.views import hello, current_datetime, hours_ahead
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^hello/$', hello),
url(r'^time/$', current_datetime),
url(r'^time/plus/(\d{1,2})/$', hours_ahead),
]
If you’re experienced in another Web development platform, you may be thinking, “Hey, let’s use a query string parameter!” – something like /time/plus?hours=3
, in which the hours would be designated by the hours parameter in the URL’s query string (the part after the ‘?’).You can do that with Django (and I’ll tell you how in Chapter 7), but one of Django’s core philosophies is that URLs should be beautiful. The URL /time/plus/3/ is far cleaner, simpler, more readable, easier to recite to somebody aloud and . . . just plain prettier than its query string counterpart. Pretty URLs are a characteristic of a quality Web application.(如果你在其他的Web开发平台有经验的话,你可能会想“嘿, 用字符串查询参数不就好了? ” 就像 /time/plus?hours=3 , 小时的数目将会被设计成在URL里面的字符查询参数。你将会在Django的第七章中知道如何这样做,但是Django的核心哲学之一时URL必须是漂亮的。/time/plus/3 是更清晰,简单可读的,容易大声的想某人背诵出来,比字符串查询参数设计的更加漂亮,漂亮的URL是一个Web应用程序高质量的体现。)
Django’s URLconf system encourages pretty URLs by making it easier to use pretty URLs than not to.(Django的URL配置系统鼓励更漂亮的URL格式让他用起来更简单)
With that taken care of, let’s write the hours_ahead
view. hours_ahead
is very similar to the current_datetime
view we wrote earlier, with a key difference: it takes an extra argument, the number of hours of offset. Here’s the view code:(让我们开始写hours_ahead
视图函数,hours_ahead
和current_datetime是
非常相似的简单,其中的一个非常重要的不同就是:他需要一个额外的参数,一个时间偏移量的数字。下面是试图代码)
from django.http import Http404, HttpResponse
import datetime def hours_ahead(request, offset):
try:
offset = int(offset)
except ValueError:
raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
html = "In %s hour(s), it will be %s." % (offset, dt)
return HttpResponse(html)
Let’s take a closer look at this code.(让我们更加仔细的看一下这个代码)
The view function, hours_ahead
, takes two parameters: request
and offset
:(视图函数hours_ahead需要两个参数 request和offset)
request
is anHttpRequest
object, just as inhello
andcurrent_datetime
. I’ll say it again: each view always takes anHttpRequest
object as its first parameter.(request是一个HttpRequest对象,就像上面的hello和current_datetime。我要再次说一下:每一个视图函数总会有一个HttpRequest对象在第一个参数。
)offset
is the string captured by the parentheses in the URLpattern. For example, if the requested URL were/time/plus/3/
, then offset would be the string ‘3’. If the requested URL were/time/plus/21/
, then offset would be the string ‘21’. Note that captured values will always be Unicode objects, not integers, even if the string is composed of only digits, such as ‘21’.(偏移量是在URLpattern的括号中捕捉的。例如,如果这个请求URL是 /time/plus/3 ,那么 offset就是是字符串格式的“21”.注意捕获的对象永远都是Unicode对象,不是integers类型的,就算这个字符仅有数字组成例如“21”)
I decided to call the variable offset
, but you can call it whatever you’d like, as long as it’s a valid Python identifier. The variable name doesn’t matter; all that matters is that it’s the second argument to the function, after request
.(我决定叫这个变量为offset,但是你可以叫他任何你喜欢的玩意,只要他是一个合法的Python标识符。变量名是不重要的,最重要的是他是在request之后的第二变量)
(It’s also possible to use keyword, rather than positional, arguments in an URLconf. I cover that in Chapter 7.)(他也可能用关键字,而不是位置,妈的翻译不动了)
The first thing we do within the function is call int()
on offset
. This converts the Unicode string value to an integer.(第一件事情就是对着offset来一套int(),他把Unicode类型的字符串转化成整数类型)
Note that Python will raise a ValueError
exception if you call int()
on a value that cannot be converted to an integer, such as the string “foo”.(注意Python会收集到ValueError异常 如果你调用int()然后不能转化到int 类型,例如字符串“foo”)
In this example, if we encounter the ValueError
, we raise the exception django.http.Http404
, which, as you can imagine, results in a 404 “Page not found” error.(在这个例子里面,如果我们遇到ValueError错误,我们 raise exception django.http.Http404
,正如你所想的那样,结果回事404 page not found 页面。 )
Astute readers will wonder: how could we everthe ValueError
case, anyway, given that the regular expression in our URLpattern – (\d{1,2})
– captures only digits, and therefore offset
will only ever be a string composed of digits? The answer is, we won’t,
because the URLpattern provides a modest but useful level of input
validation, but we still check for the ValueError
in case this view function ever gets called in some other way. It’s good
practice to implement view functions such that they don’t make any
assumptions about their parameters. Loose coupling, remember?(聪明的读者会有疑问:我们怎样会因此ValueError呢? anyway 我们在URLpattern中给出了正则表达式(\d{1,2}) 只会捕捉数字,因此offset只会是数字组成的,答案是不会的。因为URLpattern 提供了一个有用且适度的输入验证。但是我们仍然会检查ValueError这个错误以防在某些想不到的地方被调用。这是一个很好的练习去实现视图函数,他们不做任何假设的参数。松散耦合,记得么?)
In the next line of the function, we calculate the current date/time
and add the appropriate number of hours. We’ve already seen datetime.datetime.now()
from the current_datetime
view; the new concept here is that you can perform date/time arithmetic by creating a datetime.timedelta
object and adding to a datetime.datetime
object. Our result is stored in the variable dt
.(这个函数的下一行,我们计算了当前时间 date/time and 增加了一个适当的时间,我们已经从current_datetime
的视图函数中见到过datetime.datetime.now(),这个新的概念时你可以执行 date/time 算数运算 通过创建一个datetime.timedelta 对象 并且加上一个datetime.datetime 对象,我们的结果储存在dt变量当中。
)
This line also shows why we called int()
on offset
– the datetime.timedelta
function requires the hours
parameter to be an integer. (这一行也说明了我们为什么对offset函数执行int() 操作。datetime.timedelta函数 时间参数必须为intger 类型。)
Next, we construct the HTML output of this view function, just as we did in current_datetime
. A small difference in this line from the previous line is that it uses Python’s format-string capability with two values, not just one. Hence, there are two %s
symbols in the string and a tuple of values to insert: (offset, dt)
. (接下来 , 我们对这个视图函数构造HTML输出,就像我们在current_datetime
做的那样。一个小小的不同是他用了带有两个值的Python格式化字符串而不是一个值。因此这里有两个 %s 符号在字符串里面,和一个插入数据的元祖(offset,dt))
Finally, we return an HttpResponse
of the HTML.(最终我们返回一个HttpResponse的HTml)
With that view function and URLconf written, start the Django development server (if it’s not already running), and visit http://127.0.0.1:8000/time/plus/3/
to verify it works.(随着写完视图函数和URLconf,我们开始运行我们的Django开发扶我去(如果他现在没有运行的话),访问http://127.0.0.1:8000/time/plus/3/
验证他的工作)
Then try http://127.0.0.1:8000/time/plus/5/
.(然后试着访问 。。。)
Then http://127.0.0.1:8000/time/plus/24/
.(。。。)
Finally, visit http://127.0.0.1:8000/time/plus/100/
to
verify that the pattern in your URLconf only accepts one- or two-digit
numbers; Django should display a “Page not found” error in this case,
just as we saw in the section “A Quick Note About 404 Errors” earlier.(最终访问http://127.0.0.1:8000/time/plus/100/
以验证你的URLconf 只能接受一个或者两个数字,Django会展现一个“Page not found” 错误在这个例子里面,就像我们在“A Quick Note About 404 Errors”这一小节里面看到的一样)
The URL http://127.0.0.1:8000/time/plus/
(with no hour designation) should also throw a 404.(http://127.0.0.1:8000/time/plus/
没有定义时间,因此他也会抛出404错误)
Django’s Pretty Error Pages(Django 漂亮的出错页面)
Take a moment to admire the fine Web application we’ve made so far . .
. now let’s break it! Let’s deliberately introduce a Python error into
our views.py
file by commenting out the offset = int(offset)
lines in the hours_ahead
view:(花一点时间来欣赏我们已经做好的Web应用吧!然后让我们做一点破坏吧!现在让我们故意引入一个Python的错误到我们的views.py文件中通过注释掉offset = int(offset)
这一行在我们的hours_ahead
视图函数里面)
def hours_ahead(request, offset):
# try:
# offset = int(offset)
# except ValueError:
# raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
html = "In %s hour(s), it will be %s." % (offset, dt)
return HttpResponse(html)
Load up the development server and navigate to /time/plus/3/
. You’ll see an error page with a significant amount of information, including a TypeError
message displayed at the very top: "unsupported type for timedelta hours component: str"
(Figure 2-3).(加载开发服务器and进入/time/plus/3/
,你将会看到错误页包含了大量的错误信息,包含了类型错误信息,展现在顶部“不支持的timedelta时间组件:str”)
Figure 2-3: Django’s error page(Django的错误页)
What happened? Well, the datetime.timedelta
function expects the hours
parameter to be an integer, and we commented out the bit of code that converted offset
to an integer. That caused datetime.timedelta
to raise the TypeError
. It’s the typical kind of small bug that every programmer runs into at some point.(发生了什么呢?是的,datetime.timedelta函数要让时间参数为整数,and我们注释掉了一些将offset转化为integer为整数的代码。这导致了datetime.timedelta弹出了TypeError错误。这是一种典型的 小bug,而且每个程序员都会遇到这种错误在某时。)
The point of this example was to demonstrate Django’s error pages. Take some time to explore the error page and get to know the various bits of information it gives you. Here are some things to notice:(这个例子的关键是为了演示Django的错误页。花一点时间去探究这个错误页and了解给你的各种错误信息,这里是一些注意事项:)
- At the top of the page, you get the key information about the exception: the type of exception, any parameters to the exception (the
"unsupported type"
message in this case), the file in which the exception was raised, and the offending line number.(在这个页面的顶部,你会得到关键的错误信息:错误类型,任何异常参数(在这个例子中的信息就是“不支持的类型”),在那个文件出现了异常和出错行) - Under the key exception information, the page displays the full Python traceback for this exception. This is similar to the standard traceback you get in Python’s command-line interpreter, except it’s more interactive. For each level (“frame”) in the stack, Django displays the name of the file, the function/method name, the line number, and the source code of that line.(在关键的错误信息下面,页面展示了完整的Python错误追踪信息。这类似于你在Python的命令行中追踪到的信息,只不过后者更有交互性,对栈中的每一帧,Django均显示了该文件名,该方法或者函数的名称,行号和源代码。)
- Click the line of source code (in dark gray), and you’ll see several lines from before and after the erroneous line, to give you context. Click “Local vars” under any frame in the stack to view a table of all local variables and their values, in that frame, at the exact point in the code at which the exception was raised. This debugging information can be a great help.(点击这一行代码(深灰色的代码),and你会看到数行错误的源代码,给你内容,点击“Local vars”可以看到所有局部变量的列表以及在出错时那一栈帧的值,这将会有极大的帮助。)
- Note the “Switch to copy-and-paste view” text under the “Traceback” header. Click those words, and the traceback will switch to an alternate version that can be easily copied and pasted. Use this when you want to share your exception traceback with others to get technical support – such as the kind folks in the Django IRC chat room or on the Django users mailing list.(注意这“Switch to copy-and-paste view”文本在“Traceback”后面,点击这些话会切换到另一个试图,他会让你很容易的复制和粘贴这些内容。当你想同其他人分享这些异常以获得技术支持的话可以使用它)
- Underneath, the “Share this traceback on a public Web site” button will do this work for you in just one click. Click it to post the traceback to dpaste, where you’ll get a distinct URL that you can share with other people.(点击“分享追中信息到公开Web站点”按钮,会自动做完这些工作。点击他以传回信息到dpaste,在哪里你会得到一个单独的URL并传给其他人分享你的追踪信息。)
- Next, the “Request information” section includes a wealth of information about the incoming Web request that spawned the error:
GET
andPOST
information, cookie values, and meta information, such as CGI headers. Appendix F has a complete reference of all the information a request object contains.(接下来“Request information”部分包含了有关产生错误的 Web 请求的大量信息: GET 和 POST、cookie 值、元数据(象 CGI 头)。 在附录H里给出了request的对象的 完整参考。) - Below the “Request information” section, the “Settings” section lists all of the settings for this particular Django installation. All the available settings are covered in detail in Appendix D.(Request信息的下面,“Settings”列出了 Django 使用的具体配置信息。 (我们已经提及过ROOT_URLCONF,接下来我们将向你展示各式的Django设置。 附录D覆盖了所有可用的设置。))
The Django error page is capable of displaying more information in certain special cases, such as the case of template syntax errors. We’ll get to those later, when we discuss the Django template system. For now, uncomment the offset = int(offset)
lines to get the view function working properly again.(Django 的出错页某些情况下有能力显示更多的信息,比如模板语法错误。 我们讨论 Django 模板系统时再说它们。 现在,取消 offset = int(offset) 这行的注释,让它重新正常 工作。)
The Django error page is also really useful if you are the type of programmer who likes to debug with the help of carefully placed print
statements.(Django的错误页也是非常有用的如果你是这种程序员---喜欢小心翼翼的使用print去debug的人。)
At any point in your view, temporarily insert an assert False
to trigger the error page. Then, you can view the local variables and state of the program. Here’s an example, using the hours_ahead
view:(在你视图的任何位置,临时插入一个 assert False 来触发出错页。 然后,你就可以看到局部变量和程序语句了。 这里有个使用hours_ahead视图的例子:)
def hours_ahead(request, offset):
try:
offset = int(offset)
except ValueError:
raise Http404()
dt = datetime.datetime.now() + datetime.timedelta(hours=offset)
assert False
html = "In %s hour(s), it will be %s." % (offset, dt)
return HttpResponse(html)
Finally, it’s obvious that much of this information is sensitive – it exposes the innards of your Python code and Django configuration – and it would be foolish to show this information on the public Internet. A malicious person could use it to attempt to reverse-engineer your Web application and do nasty things. For that reason, the Django error page is only displayed when your Django project is in debug mode. I’ll explain how to deactivate debug mode in Chapter 13. For now, just know that every Django project is in debug mode automatically when you start it. (Sound familiar? The “Page not found” errors, described earlier in this chapter, work the same way.)(最后,很显然这些信息很多是敏感的,它暴露了你 Python 代码的内部结构以及 Django 配置,在 Internet 上公开这信息是很愚蠢的。 不怀好意的人会尝试使用它攻击你的 Web 应用程序,做些下流之事。 因此,Django 出错信息仅在 debug 模式下才会显现。 我们稍后 说明如何禁用 debug 模式。 现在,你只要知道 Django 服务器在你开启它时默认运行在 debug 模式就行了。 (听起来很熟悉? 页面没有发现错误,如前所述,工作正常。))
What’s Next?(下一节说点什么呢?)
So far, we’ve been writing our view functions with HTML hard-coded directly in the Python code. I’ve done that to keep things simple while I demonstrated core concepts, but in the real world,
this is nearly always a bad idea. Django ships with a simple yet
powerful template engine that allows you to separate the design of the
page from the underlying code. We’ll dive into Django’s template engine
in the next chapter.(目前为止,我们已经写好了视图函数和硬编码的HTML。 在演示核心概念时,我们所作的是为了保持简单。但是在现实世界中,这差不多总是个坏主意。幸运的是,Django内建有一个简单有强大的模板处理引擎来让你分离两种工作: 下一章,我们将学习模板引擎。)
Django Views: Dynamic Content的更多相关文章
- Django Views and URLconfs
碧玉妆成一树高,万条垂下绿丝绦. 不知细叶谁裁出,二月春风似剪刀. 原文尽在:http://djangobook.com/ 转载请注明出处:http://www.cnblogs.com/A-FM/p/ ...
- Django—views系统:views基础
Django的View(视图)简介 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错 ...
- Django views 中 View decorators
decorators(装饰器) 1. require_http_methods 在django.views.decorators.http中,可以用来限制请求的权限. require_http_met ...
- swipe js dynamic content
swipe js dynamic content swipe 动态改变内容时,需要用 update 一下. swiper.update(true); 实例: HTML Code 页面用的FreeMa ...
- django views视图函数返回值 return redirect httpresponse总结
django views视图函数返回值 return redirect render httpresponse总结
- django views视图函数
Django views.py视图文件 一. 创建views.py文件,在工程文件夹根目录创建views.py视图文件,其实任意文件名都可以,使用views是为了遵循传统. 注:所有的views函数都 ...
- Django Views Decorator
Django的试图函数的装饰器主要有: HTTP请求方法 条件视图处理 GZip压缩 改变页眉 缓存 官网文档 HTTP请求方法 该装饰器是设置允许访问HTTP协议的方法,装饰器在django.vie ...
- Django~Views
In Django, web pages and other content are delivered by views. To get from a URL to a view, Django u ...
- Django Views(视图函数)
http请求中产生两个核心对象: http请求:HttpRequest对象 http响应:HttpResponse对象 所在位置:django.http 之前我们用到的参数request就是HttpR ...
随机推荐
- Android自己定义组件系列【11】——实现3D立体旋转效果
今天在网上看到一篇文章写关于Android实现3D旋转(ca=drs-">http://www.ibm.com/developerworks/cn/opensource/os-cn-a ...
- Django-权限信息中间件操作
# 在当前app下新建一个middleware的文件夹,然后就可以尽情的写中间件了,只能是这个名字,切记~@!import re from django.shortcuts import redire ...
- 程序员笔记|Spring IoC、面向切面编程、事务管理等Spring基本概念详解
一.Spring IoC 1.1 重要概念 1)控制反转(Inversion of control) 控制反转是一种通过描述(在java中通过xml或者注解)并通过第三方去产生或获取特定对象的方式. ...
- adb的那点小事——360电视助手实现研究
欢迎转载,转载请注明:http://blog.csdn.net/zhgxhuaa 1. 前言 1.1. 行业背景简单介绍 当下,智能家居与智能穿戴设备无疑是继智能手机后两个最热门的方向.而智能家 ...
- Java堆内存与栈内存对比
在数据结构中,堆和栈可以说是两种最基础的数据结构,而Java中的栈内存空间和堆内存空间有什么异同,以及和数据结构中的堆栈有何关系? 一.Java 堆存储空间 堆内存(堆存储空间)会在Java运行时分配 ...
- storage engine option for directoryPerDB
Requested option conflicts with current storage engine option for directoryPerDB; you requested true ...
- andfix使用
1.andfix简介 AndFix是一个Android App的在线热补丁框架.使用此框架,我们能够在不重复发版的情况下,在线修改App中的Bug.AndFix就是 “Android Hot-Fix” ...
- hdoj 1875 畅通project再续【最小生成树 kruskal && prim】
畅通project再续 Problem Description 相信大家都听说一个"百岛湖"的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其它的小岛时都要通过划小船来实现. ...
- spring 相关博客
Spring中使用Interceptor拦截器 spirng4 中文文档 ssm整合 Spring系列之Spring常用注解总结 Spring框架中context-param与servlet中in ...
- filename extension
题目描述 Please create a function to extract the filename extension from the given path,return the extra ...