编写你的Django应用,第1部分
让我们通过例子学习。
本教程中,我们将带领你创建一个基本的投票应用。
它包含两部分:
- 一个公开的网站,可以让访客查看投票的结果并让他们进行投票。
- 一个后台管理网站,你可以添加、修改和删除选票。
如果你已经安装了Django。你可以运行下面的命令来查看你的Django版本号。
$ python -m django --version
如果Django已经安装,你应该看到安装的版本号。如果还没有安装,你会看到一个“No module named django”的错误。
本教程是针对Django 1.11和Python 3.4或更高版本编写的。如果Django版本不符,可以通过当前页面右下角的版本转换器查看适用于你所使用的版本的Django教程,或者把Django升级到最新的版本。如果你还在使用2.7版本的Python,你将需要按照注释中的内容稍微调整一下示例代码。
关于如何删除旧版本的Django并安装一个新的,请参见如何安装 Django中的建议关于如何删除旧版本的Django并安装一个新的,请参见如何安装 Django中的建议
创建一个项目
如果这是你第一次使用Django,你需要完成一些初始化设置。 你需要自己用代码来创建一个Django项目 ——一个Django框架开发的网站,创建项目后我们需要的配置的东西,包括数据库的配置、针对Django的配置选项和app的配置选项。
在命令行(终端)中,cd(例如cd exam)到你想要用来保存代码的目录,然后运行如下命令:
$ django-admin startproject mysite
这将会在你的当前目录下生成一个mysite目录。如果它不能正常工作,请查看运行django-admin遇到的问题。
注意
你给项目命名时,项目名称不能和Python或Django的 内部组件名称同名。尤其,你应该避免使用类似django(与Django自身冲突)或 test(与Python内建的包冲突)这样的名称。
代码应该存在哪里?
如果你曾经学过普通的旧式的PHP(没有使用过现代的框架),你可能习惯于将代码放在Web服务器的文档根目录下(例如/var/www)。但是对于Django,你不该这么做。将Python代码放在你的Web服务器的根目录不是个好主意,因为它可能会有让别人在网上看到你的代码的风险。这样不安全。
将你的代码放置在Web服务器根目录以外的地方,例如/home/mycode。
让我们看一下 start project 生成了什么
mysite/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
这些文件包括:
外层的 mysite/ 根目录仅仅是项目的一个容器。它的命名对Django无关紧要, 你可以把它重新命名为任何你喜欢的名字。
manage.py:一个命令行工具,可以使你用多种方式对Django项目进行交互。你可以在django-admin和manage.py中读到关于manage.py 的所有细节。
内层的 mysite/ 目录是你的项目的真正的Python包。 它是你导入任何东西时将需要使用的Python包的名字(例如mysite.urls)。
mysite/init.py:一个空文件,它告诉Python这个目录应该被看做一个Python包。 (如果你是一个Python初学者,关于包的更多内容请阅读Python的官方文档)。
mysite/settings.py:该Django 项目的设置/配置。 Django 设置 将告诉你这些设置如何工作。
mysite/urls.py:该Django项目的URL声明, 你的Django站点的“目录”。
你可以在URL 转发器 中阅读到更多关于URL的内容。mysite/wsgi.py:用于你的项目的与WSGI兼容的Web服务器入口。
更多细节请参见如何利用WSGI进行部署。
开发服务器
我们验证一下你的Django项目是否工作。 如果你不在外层的mysite目录下,那么进入这个目录,然后运行以下命令:
$ python manage.py runserver
你将看到命令行下输出了以下内容:
Run 'python manage.py migrate' to apply them.
November 30, 2017 - 20:42:17
Django version 1.11.6, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
这表明你已经启动了Django开发服务器,一个用纯Python写的轻量级Web服务器。 我们在Django中内置了它,这样你就可以在不配置用于生产环境的服务器 —— 例如Apache —— 的情况下快速开发出产品,直到你准备好上线。
请注意:不要在任何生产环境使用这个服务器。它仅仅是用于在开发中使用。(我们的重点是编写Web框架,非Web服务器。)
既然服务器已经运行,请用你的浏览器访问 http://127.0.0.1:8000/。在淡蓝色背景下,你将看到一个“Welcome to Django”的页面。它运行成功了!
更改端口
默认情况下,runserver 命令在内部IP的8000端口启动开发服务器。
如果你需改变服务器的端口,把要使用的端口作为一个命令行参数传递给它。 例如,这个命令在8080端口启动服务器:
$ python manage.py runserver 8080
如果你需改变服务器的IP地址,把IP地址和端口号放到一起。 因此若要监听所有的外网IP,请使用(如果你想在另外一台电脑上展示你的工作,会非常有用):
$ python manage.py runserver 0.0.0.0:8000
runserver的自动重载
开发服务器会根据需要自动重新载入Python代码。 你不必为了使更改的代码生效而重启服务器。 然而,一些行为比如添加文件,不会触发服务器的重启,所以在这种情况下你需要手动重启服务器。
创建Pools应用
现在,你的开发环境 —— 一个“项目” —— 已经建立起来,你将开始在上面做一些东西。
你编写的每个Django应用都是遵循特定约定且包含一个Python包。 Django自带一个工具,它可以自动生成应用的基本目录结构,这样你就能专心于书写代码而不是创建目录。
项目 vs. 应用
项目和应用之间有什么不同? 应用是一个Web应用程序,它完成具体的事项 —— 比如一个博客系统、一个存储公共档案的数据库或者一个简单的投票应用。 项目是一个特定网站中相关配置和应用的集合。一个项目可以包含多个应用。一个应用可以运用到多个项目中去。
你的应用可以放在Python path上的任何位置。在本教程中,我们将在你的manage.py
文件同级目录创建我们的投票应用,以便可以将它作为顶层模块导入,而不是mysite的子模块。
要创建您的应用程序,请确保您与manage.py在同一目录中,并键入以下命令:
$ python manage.py startapp polls
这将创建一个目录polls,它的结构如下:
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py
我们的polls应用将基于这个目录结构。
编写你的第一个视图
让我们来编写第一个视图。 打开polls/views.py
文件并将以下Python代码写入:
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the polls index.")
这可能是Django中最简单的视图。为了能够调用这个视图,我们需要将这个视图映射到URL上 —— 利用一个URLconf。
要在polls目录中创建一个URLconf,创建一个名为urls.py
的文件。你的应用的目录现在看起来应该像这样。
polls/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
urls.py
views.py
在polls/urls.py
文件中键入如下代码:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
下一步是将根URLconf指向polls.urls模块。 在mysite/urls.py
中,从django.conf.urls.导入include,并且插入Include()
到 urlpatterns列表, 这样你就有了:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^polls/', include('polls.urls')),
url(r'^admin/', admin.site.urls),
]
Include()
函数允许引用其他URLconf。 请注意,Include()
函数的正则表达式不具有$(字符串结束匹配符),而是尾部斜线。每当Django遇到Include()
时,它将删除与此相匹配的URL部分,并将剩余的字符串发送到包含的URLconf进行进一步处理。
Include()
背后的想法是即插即用使网址变得容易。 由于投票应用是在自己的URLconf(pool/ urls.py
),它们可以放在“/polls/”下或“/fun_polls/”下或“/content/polls/”下,或任何其他路径根,并且应用程序仍然可以工作。
何时使用Include()
当你要包含其他URL模式时,应始终使用Include()
。 admin.site.urls是唯一的例外。
与你看到的不一致?
如果你看到的是include(admin.site.urls)而不是admin.site.urls,你可能使用的是一个与本教程版本不匹配的Django版本。 你应该切换到旧版本或者新版本的Django。
你现在已将index视图连接到URLconf中。 让我们验证它的工作,运行以下命令:
$ python manage.py runserver
在浏览器中转到http://localhost:8000/polls/,你应该看到文本“ Hello, world.
You're at the polls index. ”,这是你在 index 视图中定义的。
url()
函数传递四个参数,两个必选参数:regex和view,两个可选参数:kwargs和name。 在这里,值得重新审视这些参数。
url()
参数:regex
术语“regex”是一种常用的缩写,意思是“正则表达式”,它是用于匹配字符串中的模式的语法,换言之,在这里是匹配url。 Django从第一个正则表达式开始,在列表中自上而下匹配,将请求的URL与每个正则表达式进行比较,直到找到匹配的一个。
请注意,这些正则表达式不搜索GET和POST参数或域名。 例如,在https://www.example.com/myapp/
的请求中,URLconf将查找myapp/
。 在https://www.example.com/myapp/?page=3
的请求中,URLconf仍将查找myapp/。
如果你需要正则表达式的帮助,请参阅维基百科的条目和re模块的文档。 此外,由Jeffrey Friedl撰写的O'Reilly书“精通正则表达式”非常棒。 但实际上,你不需要成为正则表达式的专家,因为你只需要知道如何捕获简单的模式。 实际上,复杂的正则表达式的查找性能可能很差,所以你可能不应该依靠正则表达式的全部功能。
最后,一个性能提示:这些正则表达式是第一次加载URLconf模块时被编译。 它们超级快(只要查找不是太复杂,如上所述)。
url()
参数:view
当Django发现正则表达式匹配时,Django将调用指定的视图函数,使用 HttpRequest
对象作为第一个参数,并将正则表达式中的任何“捕获”值作为其他参数。
如果正则表达式使用简单的捕获,则值作为位置参数传递;如果它使用命名捕获,则值作为关键字参数传递。
我们稍后会给出一个例子。
url()
参数:kwargs
任意关键词参数可以在字典中传递到目标视图。
我们不会在该教程中使用Django的这个功能。
url()
参数:name
命名你的URL可让你从Django其他地方明确地引用它,特别是在模板中。
这个强大的功能允许你在仅接触单个文件的情况下对项目的URL模式进行全局更改。
当你对基本请求和响应的流程感到满意时,请阅读 本教程的第2部分 开始与数据库一起工作。