1、作为我们的第一个目标,让我们创建一个web页面来输出这个著名的示例消息:Hello world。如果您在没有web框架的情况下发布了一个简单的Hello world web页面,那么您只需将Hello world输入到一个文本文件中,并将其命名为Hello.html文件,并将其上传到某个web服务器上的某个目录。请注意在这个过程中您已经指定网页的两条最重要的信息:其内容(字符串“Hello world”)和它的URL(例如,http://www.example.com/hello.html)。
2、在Django的情况下,你可以指定这两件事,但以不同的方式。该页面的内容由一个视图函数生成,URL在URLconf中指定。首先,让我们来编写Hello world视图函数。
我们在上一章创建的内部mysite目录中的第一个视图,创建一个名为views.py的空文件。这个Python模块将包含本章的视图。确保将文件放在内部mysite目录中,即mysite\mysite\ 目录,而不是包含manage.py的目录。我们的Hello world视图很简单。这里是整个函数,加上import语句,您应该将它们输入到views.py文件中。
from django.http import HttpResponse def hello(request): return HttpResponse("Hello world")
让我们一次一步一步地完成这一行代码:首先,我们导入类的类,它位于django中http模块。我们需要导入这个类,因为它稍后在我们的代码中使用。
接下来,我们定义一个名为hello视图函数的函数。每个视图函数至少需要一个参数,按约定称为请求。这是一个包含触发该视图的当前web请求的信息,也是类django.http..http的一个实例。
在本例中,我们不使用请求做任何事情,但它必须是视图的第一个参数。注意,视图函数的名称并不重要; 为了让Django意识到这一问题,它不需要以某种方式命名。
我们在这里称它为hello,因为这个名字清楚地表明了这个观点的主旨,但是它也可以被命名为hello_wonderful_beautiful_world,或者同样令人作呕的东西。
下一节,你的第一个URLconf,将阐明Django是如何找到这个功能的。这个函数是一个简单的一行程序:它仅仅返回一个已经用文本“Hello world”实例化的HttpResponse 对象。这里的主要经验是:视图仅仅是一个Python函数,它将一个参数作为它的第一个参数,并返回一个关于HttpResponse的实例。
为了让Python函数成为Django视图,它必须做这两件事。(也有例外,但我们稍后会讲到。
在这一点上,您的第一个URLconf 需要再一次运行python manage.py runserver 命令,你仍然可以看到Django的信息,在我们的Hello world视图中没有任何改变。这是因为我们的mysite项目还不知道hello视图;我们需要明确地告诉Django,我们在一个特定的URL上激活了这个视图。
继续我们之前的关于发布静态HTML文件的类比,现在我们已经创建了HTML文件,但是没有将它上传到服务器上的一个目录中。
为了将视图函数与Django的特定URL连接在一起,我们使用了一个URLconf。
URLconf类似于您的django驱动的web站点的内容表。基本上,它是url和应该调用这些url的视图函数之间的映射。这是你告诉Django的,因为这个URL,调用这个代码,并为那个URL调用代码。例如,当某人访问URL/foo/时,调用视图函数fooview(),它位于Python模块views.py中。
在前一章中执行了django-admin startproject时,脚本为您自动创建了一个URLconf:文件urls.py。
默认情况下,它是这样的
"""mysite URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r‘^$‘, views.home, name=‘home‘) Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r‘^$‘, Home.as_view(), name=‘home‘) Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r‘^blog/‘, include(‘blog.urls‘)) """ from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r‘^admin/‘, admin.site.urls), ]
如果我们忽略文件顶部的文档注释,这里是URLconf的本质
from django.conf.urls import url from django.contrib import admin urlpatterns = [ url(r‘^admin/‘, admin.site.urls), ]
让我们一次一步一步地完成这段代码:第一行从django.conf.urls模块 导入两个函数。包括允许您将完整的Python导入路径包含到另一个URLconf模块,以及使用正则表达式将浏览器中的url与Django项目中的模块匹配的url。第二行从django.contrib模块中
调用函数admin。这个函数由include函数调用,以加载Django管理站点的url。
第三行是urlpatterns
,一个简单的url()实例列表。
这里要注意的主要问题是可变的urlpatterns,Django希望在你的URLconf模块中找到它。这个变量定义了url和处理这些url的代码之间的映射。要向URLconf添加URL和视图,只需在URL模式和视图函数之间添加一个映射。这里是如何在hello视图中连接
from django.conf.urls import url from django.contrib import admin from mysite.views import hello urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^hello/$‘, hello), ]
我们在这里做了两个更改:首先,我们从它的模块mysite/views.py中导入hello视图,它转化为mysite。Python导入语法中的视图。(这个假设mysite /views.py在您的Python路径上。)接下来,我们向 urlpatterns 添加了行url(r‘hello/$‘,hello)。这 一行被称为URLpattern。这个url()函数告诉Django如何处理你正在配置的url。第一个参数是一个模式匹配字符串(一个正则表达式;更详细地讨论这个)第二个参数是用于该模式的视图函数。url()也可以选择其他可选的参数,我们将在第7章更深入地讨论这个问题。
我们在这里介绍的一个更重要的细节是正则表达式字符串前面的r字符。
这告诉Python,字符串是一个原始字符串,它的内容不应该解释反斜杠。
在普通的Python字符串中,反斜杠用于转义字符串n中的特殊字符,字符串n是一个包含换行符的字符字符串。
当您将r添加为一个原始字符串时,Python并没有应用它的反斜杠,因此r‘\n‘是一个包含一个文本反斜杠和一个小写n的双字符字符串。
Python的反斜杠和正则表达式中找到的反斜杠之间存在自然冲突,所以在您重新定义Django的正则表达式时,最好使用原始字符串。
简单地说,我们刚刚告诉Django,任何对URL/hello/ 的请求都应该由hello视图函数处理。
值得讨论的是这个URLpattern的语法,因为它可能不那么明显。
尽管我们想要匹配URL/hello/,但是模式看起来有点不同。
这是为什么
Django在检查URL模式之前,从每个输入的URL前删除了这个斜杠。
这意味着我们的URLpattern不包括/hello/中的主要斜杠。
一开始,这可能看起来不太直观,但这一要求简化了诸如在其他URLconfs中包含URLconfs的内容,我们将在第7章中介绍。
该模式包括一个caret (^)和一个美元符号($)。
这些是具有特殊含义的正则表达式字符:caret (^)意味着模式与字符串的开始匹配,而美元符号表示模式与字符串的结尾匹配。
这个概念最好用例子来解释,如果我们使用的是模式hello/(在最后没有美元符号), If we had instead used the pattern ^hello/(without a dollar sign at the end), then any URL starting with /hello/ would match, such as /hello/foo and /hello/bar, not just /hello/.
Similarly 类似地, if we had left off 保留 the initial caret character (i.e., hello/$), Django would match 匹配 any URL that ends with hello/, such as /foo/bar/hello/. If we had simply used hello/, without a caret or dollar sign, then any URL containing 包含 hello/ would match, such as /foo/hello/bar.Thus, 因此 we use both the caret and dollar sign to ensure 确保 that only the URL /hello/ matches nothing more 更多, nothing less 更少.