===================================== 编写您的第一个Django应用, 第1部分 ===================================== 让我们通过例子来学习。 在本教程中,我们将引导您创建一个基本的投票应用。 它将包含两部分: * 一个公共网站,可让人们查看投票的结果和让他们进行投票。 * 一个管理网站,可让您添加、修改和删除投票项目。 我们假设您已经 :doc:`安装了 Django `。您可以通过在shell提示符(由$前缀指示)中 运行以下命令来查看是否安装了 Django 和运行的版本号: .. code-block:: console $ python -m django --version 如果 Django 已经安装,您应该能看到安装的版本号。如果还没有安装,您会看到一个 “No module named django”的错误。 可以通过当前页面右下角的版本转换器查看适用于您所使用的版本的 Django 教程, 或者把 Django 升级到最新的版本。如果您还在使用2.7版本的Python,您将需要按照注释中的 内容稍微调整一下示例代码。 关于如何删除旧版本的 Django 并安装一个新的,请参见 :doc:`如何安装 Django ` 中的建议。 .. admonition:: 在哪里可以获得帮助: 如果您在学习本教程中遇到问题,请在 |django-users| 上发贴或者在 `#django on irc.freenode.net `_ 上与其他可能会帮助您的 Django 用户交流。 创建一个项目 ================== 如果这是您第一次使用Django,那么您必须进行一些初始设置。也就是通过自动生成代码来 建立一个 Django 项目( :term:`project`)—— 一个 Django 项目的设置集,包含了数据库配置、 Django 详细选项设置和应用特性配置。 在命令行中, ``cd`` 到进入您想存储代码的目录,然后运行以下命令: .. code-block:: console $ django-admin startproject mysite 这将在当前目录创建一个 ``mysite`` 目录。如果失败了,请查看 :ref:`troubleshooting-django-admin`。 .. note:: 您需要避免使用python保留字或 Django 组件名作为项目的名称。尤其应该避免使用的命名如: ``django`` (与Django本身会冲突)或者 ``test`` (与 Python 内置的包名会冲突)。 .. admonition:: 这段代码应该放在哪里? 如果您有一般PHP的编程背景(未使用现代框架),可能会将您的代码放在Web服务器的文档根目录下 (例如: ``/var/www`` )。而在 Django 中,您不必这么做。将任何Python代码放在您的 Web服务器文档根目录不是一个好主意,因为这可能会增加人们通过Web方式查看到您的代码的风险。 这不利于安全。 将您的代码放在您的文档根目录 **以外** 的某些目录, 例如 :file:`/home/mycode`。 让我们来看看 :djadmin:`startproject` 都创建了些什么:: mysite/ manage.py mysite/ __init__.py settings.py urls.py wsgi.py 这些文件是: * 外层 :file:`mysite/` 目录只是您项目的一个容器。对于 Django 来说该目录名并不重要; 您可以重命名为您喜欢的。 * :file:`manage.py`:一个实用的命令行工具,可让您以各种方式与该 Django 项目进行交互。 您可以在 :doc:`/ref/django-admin` 中查看关于 :file:`manage.py` 的所有细节。 * 内层 :file:`mysite/` 目录是您项目中实际的Python包。该目录名就是Python包名, 通过它您可以导入它里面的任何东西。 (比如, ``mysite.urls`` )。 * :file:`mysite/__init__.py`:一个空文件,告诉Python该目录是一个Python包。 (如果您是Python新手,请查看官方文档了解 :ref:`关于包的更多内容 ` 。) * :file:`mysite/settings.py`:该 Django 项目的设置/配置。请查看 :doc:`/topics/settings` 将会告诉您如何设置。 * :file:`mysite/urls.py`:该 Django 项目的URL声明; 一份由 Django 驱动的网站“目录”。请查看 :doc:`/topics/http/urls` 阅读更多有关URL的信息。 * :file:`mysite/wsgi.py`:一个WSGI兼容的Web服务器的入口,以便运行您的项目。请查看 :doc:`/howto/deployment/wsgi/index` 获取更多细节。 开发服务器 ====================== 让我们来验证您的 Django 项目是否工作。从外层 :file:`mysite` 目录切换进去,若准备好了就运行如下命令: .. code-block:: console $ python manage.py runserver 您将会看到命令行输出如下内容: .. parsed-literal:: Performing system checks... System check identified no issues (0 silenced). You have unapplied migrations; your app may not work properly until they are applied. Run 'python manage.py migrate' to apply them. |today| - 15:50:53 Django version |version|, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. .. note:: 暂时忽略未应用数据库迁移的警告;我们将尽快处理数据库。 您已经启动了 Django 开发服务器,一个纯粹的由Python编写的轻量级Web服务器。我们在 Django 内 包含了这个服务器,这样您就可以快速开发了。在产品投入使用之前不必去配置一台生产环境下的服务器 —— 例如Apache。 现在是一个很好的提示时机:**不要** 在任何类似生产环境中使用此服务器。它仅适用于开发环境。 (我们提供的是Web框架业务,而不是Web服务器。) 现在服务器正在运行中,请在您的Web浏览器中访问 http://127.0.0.1:8000/ 。 您会看到一个令人愉悦的,淡蓝色的 “Welcome to Django” 页面。它工作了! .. admonition:: 更改端口号 默认情况下, :djadmin:`runserver` 命令启动的开发服务器只监听本地IP的8000端口。 如果您想改变服务器的端口,把它作为一个命令行参数传递即可。例如以下命令启动的服务器 将监听8080端口: .. code-block:: console $ python manage.py runserver 8080 如果您想改变服务器IP,把它和端口号一起传递即可。因此,要监听所有公共IP地址 (如果您想在其他电脑上炫耀您的工作),请使用: .. code-block:: console $ python manage.py runserver 0:8000 **0** 是 **0.0.0.0** 的简写。开发服务器的完整文档请参考 :djadmin:`runserver`。 .. admonition:: :djadmin:`runserver` 的自动重载 开发服务器根据需要自动为每个请求重新加载Python代码。您不需要重新启动服务器 以使代码更改生效。但是,一些操作(如添加文件)不会触发重启,因此在这些情况下 您必须重启服务器。 创建投票应用 ====================== 现在您的环境 —— 一个“项目” 已经建立好了,您可以开工了。 您在 Djaong 编写的每个应用都是由遵循特定规范的 Python 包组成的。Django 提供了一个 实用工具可以自动生成一个应用的基本目录架构,因此您可以专注于编写代码而不是去创建目录。 .. admonition:: 项目(Projects) vs. 应用(apps) 项目与应用之间有什么不同之处?应用是一个提供功能的 Web 应用 —— 例如:一个博客系统、 一个公共记录的数据库或者一个简单的投票系统。项目是针对一个特定Web 网站的 相关配置和其应用的组合。一个项目可以包含多个应用。一个应用可以在多个项目中使用。 您的应用可以存放在 :ref:`Python path ` 中的任何位置。在本教程中, 我们将通过您的 :file:`manage.py` 文件创建我们的投票应用,以便它可以作为顶层模块导入, 而不是作为 ``mysite`` 的子模块。 要创建您的应用,请确认与 :file:`manage.py` 文件在同一的目录下并输入以下命令: .. code-block:: console $ python manage.py startapp polls 这将创建一个 :file:`polls` 目录,其展开的样子如下所示:: polls/ __init__.py admin.py apps.py migrations/ __init__.py models.py tests.py views.py 此目录结构就是投票应用。 编写您的第一个视图 ===================== 我们来编写第一个视图。打开文件 ``polls/views.py``,并在其中放入以下Python代码: .. snippet:: :filename: polls/views.py 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`` 文件中包含以下代码: .. snippet:: :filename: 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`` 添加一个导入,并在 ``urlpatterns`` 列表中插入一个 :func:`~django.conf.urls.include`,所以您有: .. snippet:: :filename: mysite/urls.py 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), ] :func:`~django.conf.urls.include` 函数允许引用其他的 URLconfs。请注意, :func:`~django.conf.urls.include` 函数的正则表达式没有 ``$`` (字符串尾匹配), 而是尾部的斜杠。每当 Django 遇到 :func:`~django.conf.urls.include`,它会去除匹配到的部分, 并将剩余的字符串发送到被包含的 URLconf 中做进一步处理。 :func:`~django.conf.urls.include` 背后的想法是为了方便即插即用的网址。 由于民意调查是在自己的 URLconf( ``polls/urls.py`` )中,它们可以被放置在 “/polls/” 、 “/fun_polls/”、“/content/polls/” 或其他路径根下,应用程序仍可以工作。 .. admonition:: 什么时候使用 :func:`~django.conf.urls.include()` 当您包含其他 URL 模式时应常用 ``include()``。 唯一的例外是 ``admin.site.urls``。 .. admonition:: 和您看到的不匹配? 如果您看到了 ``include(admin.site.urls)`` 而不是 ``admin.site.urls``,您可能使用了 一个和教程不同的 Django 版本。您可能需要切换到老的或新的 Django 版本。 您现在已经在 URLconf 中连接了一个 ``index`` 视图。 让我们验证它是否工作,运行以下命令: .. code-block:: console $ python manage.py runserver 在浏览器中转到 http://localhost:8000/polls/,您应该看到在 ``index`` 视图中定义的文本 “*Hello, world. You're at the polls index.*”。 :func:`~django.conf.urls.url` 函数传递四个参数,两个必填: ``regex`` 和 ``view`` , 另外两个选填: ``kwargs`` 和 ``name`` 。在这一点上,值得回顾这些参数是干嘛的。 :func:`~django.conf.urls.url` 参数:regex --------------------------------------------- 术语 “regix” 是一种常用的短格式,意思是“正则表达式”,它是用于匹配字符串中的模式的语法, 或者在这种情况下是 URL 模式。Django 从第一个正则表达式开始,并将其放在列表中, 将请求的URL与每个正则表达式进行比较,直到找到匹配的一个。 请注意,这些正则表达式不会搜索 GET 和 POST 参数或域名。 例如,在 ``https://www.example.com/myapp/`` 请求中,URLconf 将查找 ``myapp/``。 在 ``https://www.example.com/myapp/?page=3`` 请求中,URLconf 还将查找 ``myapp/``。 如果您需要正则表达式的帮助,请参阅 `维基百科条目`_ 和 :mod:`re` 模块文档。 此外,Jeffrey Friedl编写 的 O'Reilly 书《Mastering Regular Expressions》是非常棒的。 然而,实践中,您不需要是正则表达式的专家,因为您只需要知道如何捕获简单的模式。 事实上,复杂的正则表达式的查找性能会很差,所以您可能不应该依赖正则表达式的全部功能。 最后,一个性能说明:这些正则表达式是在第一次加载 URLconf 模块时被编译到。它们超级快 (只要查找不是太复杂,如上所述)。 .. _维基百科条目: https://en.wikipedia.org/wiki/Regular_expression :func:`~django.conf.urls.url` 参数:view -------------------------------------------- 当 Django 发现正则表达式匹配时,Django 将调用指定的视图函数,并使用 :class:`~django.http.HttpRequest` 对象作为第一个参数,并将正则表达式中的任何“捕获”的值 作为其他参数。如果正则表达式使用简单的捕获,则值作为位置参数传递; 如果它使用命名捕获, 则值作为关键字参数传递。 我们稍后会给出一个例子。 :func:`~django.conf.urls.url` 参数:kwargs ---------------------------------------------- 任意关键词参数可以在字典中传递到目标视图。 我们不会在教程中使用 Django 的这项功能。 :func:`~django.conf.urls.url` 参数:name --------------------------------------------- 命名您的 URL 可让您从 Django 的其他地方明确地引用它,特别是在模板中。 这个强大的功能可让您全面更改项目的 URL 模式,而只需更改单个文件。 当您对基本请求和响应流程感到满意时,请阅读 :doc:`本教程的第2部分 ` 以开始使用数据库。