GVKun编程网logo

搭建你的第一个Django应用程序(简述搭建django开发环境所需要的步骤)

7

本文将为您提供关于搭建你的第一个Django应用程序的详细介绍,我们还将为您解释简述搭建django开发环境所需要的步骤的相关知识,同时,我们还将为您提供关于django1.8官方文档翻译:1-2-1

本文将为您提供关于搭建你的第一个Django应用程序的详细介绍,我们还将为您解释简述搭建django开发环境所需要的步骤的相关知识,同时,我们还将为您提供关于django 1.8 官方文档翻译: 1-2-1 编写你的第一个Django应用,第1部分、django 1.8 官方文档翻译: 1-2-2 编写你的第一个Django应用,第2部分、django 1.8 官方文档翻译: 1-2-3 编写你的第一个Django应用,第3部分、django 1.8 官方文档翻译: 1-2-4 编写你的第一个Django应用,第4部分的实用信息。

本文目录一览:

搭建你的第一个Django应用程序(简述搭建django开发环境所需要的步骤)

搭建你的第一个Django应用程序(简述搭建django开发环境所需要的步骤)

首先你要确保你机器上面安装了python:

python的相关学习资料:

其次,你还要确保你上面安装了Django:

接下来,才能进入到

很简单的操作,即在windows终端输入代码:

django-admin.py startproject mysite

即可,如:我是在我电脑的  python33\python_workspace 目录下面创建项目的

目录是你自己定的

运行命令:

django- 一个以mysite命名的应用程序

接下来就要进入到: python33\python_workspace\mysite  目录

运行代码:

python manage.py runserver 8080 默认为:8000

如下图:

启动好了服务,那么我们现在就可以通过浏览器进行访问了

在浏览器地址栏中输入:

到现在,你的第一个django应用程序就算是成功了!!!

解决方案

1.importError:No module named django.core

分析和解决方案:这是在运行命令:django-admin.py startproject mysite的时候遇到的问题,可以确定的是,在

自己机器上面django是已经成功安装了的,可以通过:

python -c

来验证;其次,已经把django-admin.py加入到了环境变量中:

E:\python33\Lib\site-packages\django\bin

我上面两步操作都做了,但是还是出现了错误,后来发现了问题的原因:我电脑上面安装的python版本过多:python2.7.5,python32,python33

最后把python2.7.5,python32卸载了,只留下python33,然后再运行,成功!!!

2.python:can't open file 'manage.py'

这个和上面的原因差不多,解决的方法,也是版本冲突,把其他卸载掉,只留下python33,成功!!!

========================================================

More reading,and english is important.

I'm Hongten

大哥哥大姐姐,觉得有用打赏点哦!多多少少没关系,一分也是对我的支持和鼓励。谢谢。Hongten博客排名在100名以内。粉丝过千。Hongten出品,必是精品。

E | hongtenzone@foxmail.com  B | 

========================================================

django 1.8 官方文档翻译: 1-2-1 编写你的第一个Django应用,第1部分

django 1.8 官方文档翻译: 1-2-1 编写你的第一个Django应用,第1部分

编写你的第一个 Django 程序 第1部分

让我们通过例子来学习。

在本教程中,我们将引导您创建一个基本的投票应用。

它将包含两部分:

  • 一个公共网站,可让人们查看投票的结果和让他们进行投票。

  • 一个管理网站,可让你添加、修改和删除投票项目。

我们假设你已经 安装了 Django 。你可以运行以下命令来验证是否已经安装了 Django 和运行着的版本号:

python -c "import django; print(django.get_version())"

你应该看到你安装的 Django 版本或一个提示你 “No module named django” 的错误。此外,还应该检查下你的版本与本教程的版本是否一致。 若不一致,你可以参考 Django 版本对应的教程或者更新 Django 到最新版本。

请参考 如何安装 Django 中的意见先删除旧版本的 Django 再安装一个新的。

在哪里可以获得帮助:

如果您在学习本教程中遇到问题,请在 django-users 上发贴或者在 #django on irc.freenode.net 上与其他可能会帮助您的 Django 用户交流。

创建一个项目

如果这是你第一次使用 Django ,那么你必须进行一些初始设置。也就是通过自动生成代码来建立一个 Django 项目 project – 一个 Django 项目的设置集,包含了数据库配置、 Django 详细选项设置和应用特性配置。

在命令行中,使用 cd 命令进入你想存储代码所在的目录,然后运行以下命令:

django-admin.py startproject mysite

这将在当前目录创建一个 mysite 目录。如果失败了,请查看 Problems running django-admin.py.

Note

你需要避免使用 python 保留字或 Django 组件名作为项目的名称。尤其是你应该避免使用的命名如: django (与 Django 本身会冲突) 或者 test (与 Python 内置的包名会冲突).

这段代码应该放在哪里?

如果你有一般 PHP 的编程背景(未使用流行的框架),可能会将你的代码放在 Web 服务器的文档根目录下(例如:/var/www)。而在 Django 中,你不必这么做。将任何 Python 代码放在你的 Web 服务器文档根目录不会是一个好主意,因为这可能会增加人们通过 Web 方式查看到你的代码的风险。这不利于安全。

将你的代码放在你的文档根目录 以外 的某些目录, 例如 /home/mycode 。

让我们来看看 startproject 都创建了些什么:

mysite/
    manage.py
    mysite/
        __init__.py
        settings.py
        urls.py
        wsgi.py

和你看到的不一样?

默认的项目布局最近刚刚改变过。如果你看到的是一个“扁平”结构的目录布局(没有内层 mysite/ 目录),你很可能正在使用一个和本教程版本不一致的 Django 版本。你需要切换到对应的旧版教程或者使用较新的 Django 版本。

这些文件是:

  • 外层 mysite/ 目录只是你项目的一个容器。对于 Django 来说该目录名并不重要; 你可以重命名为你喜欢的。

  • manage.py: 一个实用的命令行工具,可让你以各种方式与该 Django 项目进行交互。 你可以在 django-admin.py and manage.py 中查看关于 manage.py 所有的细节。

  • 内层 mysite/ 目录是你项目中的实际 Python 包。该目录名就是 Python 包名,通过它你可以导入它里面的任何东西。 (e.g. import mysite.settings).

  • mysite/init.py: 一个空文件,告诉 Python 该目录是一个 Python 包。(如果你是 Python 新手,请查看官方文档了解 关于包的更多内容 。)

  • mysite/settings.py: 该 Django 项目的设置/配置。请查看 Django settings 将会告诉你如何设置。

  • mysite/urls.py: 该 Django 项目的 URL 声明; 一份由 Django 驱动的网站“目录”。请查看 URL dispatcher 可以获取更多有关 URL 的信息。

  • mysite/wsgi.py: 一个 WSGI 兼容的 Web 服务器的入口,以便运行你的项目。请查看 How to deploy with WSGI 获取更多细节。

开发用服务器

让我们来验证是否工作。从外层 mysite 目录切换进去,若准备好了就运行命令 python manage.py runserver。你将会看到命令行输出如下内容:

Performing system checks...

0 errors found
May 13, 2015 - 15:50:53
Django version 1.8, using settings ''mysite.settings''
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

你已经启动了 Django 开发服务器,一个纯粹的由 Python 编写的轻量级 Web 服务器。我们在 Django 内包含了这个服务器,这样你就可以迅速开发了,在产品投入使用之前不必去配置一台生产环境下的服务器 – 例如 Apache 。

现在是一个很好的提示时机:不要 在任何类似生产环境中使用此服务器。它仅适用于开发环境。(我们提供的是 Web 框架的业务,而不是 Web 服务器。)

现在服务器正在运行中,请在你的 Web 浏览器中访问 http://127.0.0.1:8000/ 。 你会看到一个令人愉悦的,柔和的淡蓝色 “Welcome to Django” 页面。它工作正常!

更改端口号

默认情况下,runserver 命令启动的开发服务器只监听本地 IP 的 8000 端口。

如果你想改变服务器的端口,把它作为一个命令行参数传递即可。例如以下命令启动的服务器将监听 8080 端口:

python manage.py runserver 8080

如果你想改变服务器 IP ,把它和端口号一起传递即可。因此,要监听所有公共 IP 地址(如果你想在其他电脑上炫耀你的工作),请使用:

python manage.py runserver 0.0.0.0:8000

有关开发服务器的完整文档可以在 runserver 内参考。

数据库设置

现在,编辑 mysite/settings.py 。 这是一个普通的 Python 模块,包含了代表 Django 设置的模块级变量。 更改 DATABASES 中 ''default'' 下的以下键的值,以匹配您的数据库连接设置。

  • ENGINE – 从 ''django.db.backends.postgresql_psycopg2'', ''django.db.backends.mysql'', ''django.db.backends.sqlite3'', ''django.db.backends.oracle'' 中选一个, 至于其他请查看 also available.

  • NAME – 你的数据库名。如果你使用 SQLite,该数据库将是你计算机上的一个文件;在这种情况下,NAME 将是一个完整的绝对路径,而且还包含该文件的名称。如果该文件不存在,它会在第一次同步数据库时自动创建(见下文)。

当指定路径时,总是使用正斜杠,即使是在 Windows 下(例如:C:/homes/user/mysite/sqlite3.db) 。

  • USER – 你的数据库用户名 ( SQLite 下不需要) 。

  • PASSWORD – 你的数据库密码 ( SQLite 下不需要) 。

  • HOST – 你的数据库主机地址。如果和你的数据库服务器是同一台物理机器,请将此处保留为空 (或者设置为 127.0.0.1) ( SQLite 下不需要) 。查看 HOST 了解详细信息。

如果你是新建数据库,我们建议只使用 SQLite ,将 ENGINE 改为 ''django.db.backends.sqlite3'' 并且将 NAME 设置为你想存放数据库的地方。 SQLite 是内置在 Python 中的,因此你不需要安装任何东西来支持你的数据库。

Note

如果你使用 PostgreSQL 或者 MySQL,确保你已经创建了一个数据库。还是通过你的数据库交互接口中的 “CREATE DATABASE database_name;” 命令做到这一点的。
如果你使用 SQLite ,你不需要事先创建任何东西 - 在需要的时候,将会自动创建数据库文件。

当你编辑 settings.py 时,将 TIME_ZONE 修改为你所在的时区。默认值是美国中央时区(芝加哥)。

同时,注意文件底部的 INSTALLED_APPS 设置。它保存了当前 Django 实例已激活的所有 Django 应用。每个应用可以被多个项目使用,而且你可以打包和分发给其他人在他们的项目中使用。

默认情况下,INSTALLED_APPS 包含以下应用,这些都是由 Django 提供的:

  • django.contrib.auth – 身份验证系统。

  • django.contrib.contenttypes – 内容类型框架。

  • django.contrib.sessions – session 框架。

  • django.contrib.sites – 网站管理框架。

  • django.contrib.messages – 消息框架。

  • django.contrib.staticfiles – 静态文件管理框架。

这些应用在一般情况下是默认包含的。

所有这些应用中每个应用至少使用一个数据库表,所以在使用它们之前我们需要创建数据库中的表。要做到这一点,请运行以下命令:

python manage.py syncdb

syncdb 命令参照 INSTALLED_APPS 设置,并在你的 settings.py 文件所配置的数据库中创建必要的数据库表。每创建一个数据库表你都会看到一条消息,接着你会看到一个提示询问你是否想要在身份验证系统内创建个超级用户。按提示输入后结束。

如果你感兴趣,可以在你的数据库命令行下输入:dt (PostgreSQL), SHOW TABLES; (MySQL), 或 .schema (SQLite) 来列出 Django 所创建的表。

极简主义者

就像我们上面所说的,一般情况下以上应用都默认包含在内,但不是每个人都需要它们。如果不需要某些或全部应用,在运行 syncdb 命令前可从 INSTALLEDAPPS 内随意注释或删除相应的行。syncdb 命令只会为 INSTALLEDAPPS 内的应用创建表。

创建模型

现在你的项目开发环境建立好了, 你可以开工了。

你通过 Djaong 编写的每个应用都是由 Python 包组成的,这些包存放在你的 Python path 中并且遵循一定的命名规范。 Django 提供了个实用工具可以自动生成一个应用的基本目录架构,因此你可以专注于编写代码而不是去创建目录。

项目 ( Projects ) vs. 应用 ( apps )

项目与应用之间有什么不同之处?应用是一个提供功能的 Web 应用 – 例如:一个博客系统、一个公共记录的数据库或者一个简单的投票系统。 项目是针对一个特定的 Web 网站相关的配置和其应用的组合。一个项目可以包含多个应用。一个应用可以在多个项目中使用。

你的应用可以存放在 Python path 中的任何位置。在本教材中,我们将通过你的 manage.py 文件创建我们的投票应用,以便它可以作为顶层模块导入,而不是作为 mysite 的子模块。

要创建你的应用,请确认与 manage.py 文件在同一的目录下并输入以下命令:

python manage.py startapp polls

这将创建一个 polls 目录,其展开的样子如下所示::

polls/
    __init__.py
    models.py
    tests.py
    views.py

此目录结构就是投票应用。

在 Django 中编写一个有数据库支持的 Web 应用的第一步就是定义你的模型 – 从本质上讲就是数据库设计及其附加的元数据。

哲理

模型是有关你数据的唯一且明确的数据源。它包含了你所要存储的数据的基本字段和行为。 Django 遵循 DRY 原则 。目标是为了只在一个地方定义你的数据模型就可从中自动获取数据。

在这简单的投票应用中,我们将创建两个模型: Poll 和 ChoicePoll 有问题和发布日期两个字段。Choice 有两个字段: 选项 ( choice ) 的文本内容和投票数。每一个 Choice 都与一个 Poll 关联。

这些概念都由简单的 Python 类来表现。编辑 polls/models.py 文件后如下所示:

from django.db import models

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField(''date published'')

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

代码很简单。每个模型都由继承自 django.db.models.Model 子类的类来描述。 每个模型都有一些类变量,每一个类变量都代表了一个数据库字段。

每个字段由一个 Field 的实例来表现 – 比如 CharField 表示字符类型的字段和 DateTimeField 表示日期时间型的字段。这会告诉 Django 每个字段都保存了什么类型的数据。

每一个 Field 实例的名字就是字段的名字(如: question 或者 pub_date ),其格式属于亲和机器式的。在你的 Python 的代码中会使用这个值,而你的数据库会将这个值作为表的列名。

你可以在初始化 Field 实例时使用第一个位置的可选参数来指定人类可读的名字。这在Django的内省部分中被使用到了,而且兼作文档的一部分来增强代码的可读性。若字段未提供该参数,Django 将使用符合机器习惯的名字。在本例中,我们仅定义了一个符合人类习惯的字段名 Poll.pub_date 。对于模型中的其他字段,机器名称就已经足够替代人类名称了。

一些 Field 实例是需要参数的。 例如 CharField 需要你指定 ~django.db.models.CharField.max_length。这不仅适用于数据库结构,以后我们还会看到也用于数据验证中。

一个 Field 实例可以有不同的可选参数; 在本例中,我们将 votes 的 default 的值设为 0 。

最后,注意我们使用了 ForeignKey 定义了一个关联。它告诉 Django 每一个Choice 关联一个 Poll 。 Django 支持常见数据库的所有关联:多对一( many-to-ones ),多对多( many-to-manys ) 和 一对一 ( one-to-ones )。

激活模型

刚才那点模型代码提供给 Django 大量信息。有了这些 Django 就可以做:

为该应用创建对应的数据库架构 (CREATE TABLE statements) 。
为 Poll 和 Choice 对象创建 Python 访问数据库的 API 。
但首先,我们需要告诉我们的项目已经安装了 polls 应用。

哲理

Django 应用是“可插拔的”:你可以在多个项目使用一个应用,你还可以分发应用,因为它们没有被捆绑到一个给定的 Django 安装环境中。

再次编辑 settings.py 文件,在 INSTALLED_APPS 设置中加入 ''polls'' 字符。因此结果如下所示:

INSTALLED_APPS = (
    ''django.contrib.auth'',
    ''django.contrib.contenttypes'',
    ''django.contrib.sessions'',
    ''django.contrib.sites'',
    ''django.contrib.messages'',
    ''django.contrib.staticfiles'',
    # Uncomment the next line to enable the admin:
    # ''django.contrib.admin'',
    # Uncomment the next line to enable admin documentation:
    # ''django.contrib.admindocs'',
    ''polls'',
)

现在 Django 已经知道包含了 polls 应用。让我们运行如下命令:

python manage.py sql polls

你将看到类似如下所示内容 ( 有关投票应用的 CREATE TABLE SQL 语句 ):

BEGIN;
CREATE TABLE "polls_poll" (
    "id" serial NOT NULL PRIMARY KEY,
    "question" varchar(200) NOT NULL,
    "pub_date" timestamp with time zone NOT NULL
);
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id") DEFERRABLE INITIALLY DEFERRED,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL
);
COMMIT;

请注意如下事项:

  • 确切的输出内容将取决于您使用的数据库会有所不同。

  • 表名是自动生成的,通过组合应用名 (polls) 和小写的模型名 – poll 和 choice 。 ( 你可以重写此行为。)

  • 主键 (IDs) 是自动添加的。( 你也可以重写此行为。)

  • 按照惯例,Django 会在外键字段名上附加 "_id" 。 ( 是的,你仍然可以重写此行为。)

  • 外键关系由 REFERENCES 语句显示声明。

  • 生成 SQL 语句时针对你所使用的数据库,会为你自动处理特定于数据库的字段,例如 auto_increment (MySQL), serial (PostgreSQL), 或 or integer primary key (SQLite) 。 在引用字段名时也是如此 – 比如使用双引号或单引号。 本教材的作者所使用的是 PostgreSQL,因此例子中输出的是 PostgreSQL 的语法。

  • 这些 sql 命令其实并没有在你的数据库中运行过 - 它只是在屏幕上显示出来,以便让你了解 Django 认为什么样的 SQL 是必须的。 如果你愿意,可以把 SQL 复制并粘帖到你的数据库命令行下去执行。 但是,我们很快就能看到, Django 提供了一个更简单的方法来执行此 SQL 。

如果你感兴趣,还可以运行以下命令:

  • python manage.py validate – 检查在构建你的模型时是否有错误。

  • python manage.py sqlcustom polls – 输出为应用定义的任何 custom SQL statements ( 例如表或约束的修改 ) 。

  • python manage.py sqlclear polls – 根据存在于你的数据库中的表 (如果有的话) ,为应用输出必要的 DROP TABLE 。

  • python manage.py sqlindexes polls – 为应用输出 CREATE INDEX 语句。

  • python manage.py sqlall polls – 输出所有 SQL 语句:sql, sqlcustom, 和 sqlindexes 。

看看这些输出的命令可以帮助你理解框架底层实际上处理了些什么。

现在,再次运行 syncdb 命令在你的数据库中创建这些模型对应的表:

python manage.py syncdb

syncdb 命令会给在 INSTALLED_APPS 中有但数据库中没有对应表的应用执行 sqlall 操作。 该操作会为你上一次执行 syncdb 命令以来在项目中添加的任何应用创建对应的表、初始化数据和创建索引。 syncdb 命令只要你喜欢就可以任意调用,并且它仅会创建不存在的表。

请阅读 django-admin.py documentation 文档了解 manage.py 工具更多的功能。

玩转 API

现在,我们进入 Python 的交互式 shell 中玩弄 Django 提供给你的 API 。要调用 Python sell ,使用如下命令:

python manage.py shell

我们当前使用的环境不同于简单的输入 “python” 进入的 shell 环境,因为 manage.py 设置了 DJANGOSETTINGSMODULE 环境变量,该变量给定了 Django 需要导入的 settings.py 文件所在路径。

忽略 manage.py

若你不想使用 manage.py ,也是没有问题的。 仅需要将 DJANGOSETTINGSMODULE 环境变量值设为 mysite.settings 并在与 manage.py 文件所在同一目录下运行 python ( 或确保目录在 Python path 下,那 import mysite 就可以了 )。

想了解更多的信息,请参考 django-admin.py 文档 。

一旦你进入了 shell,就可通过 database API 来浏览数据::

>>> from polls.models import Poll, Choice   # Import the model classes we just wrote.

#  系统中还没有 polls 。
>>> Poll.objects.all()
[]

# 创建一个新 Poll 。
# 在默认配置文件中时区支持配置是启用的,
# 因此 Django 希望为 pub_date 字段获取一个 datetime  with tzinfo 。使用了 timezone.now()
# 而不是 datetime.datetime.now() 以便获取正确的值。
>>> from django.utils import timezone
>>> p = Poll(question="What''s new?", pub_date=timezone.now())

# 保存对象到数据库中。你必须显示调用 save() 方法。
>>> p.save()

# 现在对象拥有了一个ID 。请注意这可能会显示 "1L" 而不是 "1",取决于
# 你正在使用的数据库。 这没什么大不了的,它只是意味着你的数据库后端
# 喜欢返回的整型数作为 Python 的长整型对象而已。
>>> p.id
1

# 通过 Python 属性访问数据库中的列。
>>> p.question
"What''s new?"
>>> p.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# 通过改为属性值来改变值,然后调用 save() 方法。
>>> p.question = "What''s up?"
>>> p.save()

# objects.all() 用以显示数据库中所有的 polls 。
>>> Poll.objects.all()
[<Poll: Poll object>]

请稍等。<Poll: Poll object> 这样显示对象绝对是无意义的。 让我们编辑 polls 模型( 在 polls/models.py 文件中 ) 并且给 Poll 和 Choice 都添加一个 unicode() 方法来修正此错误:

class Poll(models.Model):
    # ...
    def __unicode__(self):
        return self.question

class Choice(models.Model):
    # ...
    def __unicode__(self):
        return self.choice_text

给你的模型添加 unicode() 方法是很重要的, 不仅是让你在命令行下有明确提示,而且在 Django 自动生成的管理界面中也会使用到对象的呈现。

为什么是 unicode() 而不是 str()?

如果你熟悉 Python,那么你可能会习惯在类中添加 str() 方法而不是 unicode() 方法。 We use 我们在这里使用 unicode() 是因为 Django 模型默认处理的是 Unicode 格式。当所有存储在数据库中的数据返回时都会转换为 Unicode 的格式。

Django 模型有个默认的 str() 方法 会去调用 unicode() 并将结果转换为 UTF-8 编码的字符串。这就意味着 unicode(p) 会返回一个 Unicode 字符串,而 str(p) 会返回一个以 UTF-8 编码的普通字符串。

如果这让你感觉困惑,那么你只要记住在模型中添加 unicode() 方法。 运气好的话,这些代码会正常运行。

请注意这些都是普通的 Python 方法。让我们来添加个自定义方法,为了演示而已:

import datetime
from django.utils import timezone
# ...
class Poll(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

请注意,增加了 import datetime 和 from django.utils import timezone, 是为了分别引用 Python 的标准库 datetime 模块和 Django 的 django.utils.timezone 中的 time-zone-related 实用工具 。如果你不熟悉在 Python 中处理时区,你可以在 时区支持文档 学到更多。

保存这些更改并且再次运行 python manage.py shell 以开启一个新的 Python shell:

>>> from polls.models import Poll, Choice

# 确认我们附加的  __unicode__() 正常运行。
>>> Poll.objects.all()
[<Poll: What''s up?>]

# Django 提供了一个丰富的数据库查询 API ,
# 完全由关键字参数来驱动。
>>> Poll.objects.filter(id=1)
[<Poll: What''s up?>]
>>> Poll.objects.filter(question__startswith=''What'')
[<Poll: What''s up?>]

# 获取今年发起的投票。
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Poll.objects.get(pub_date__year=current_year)
<Poll: What''s up?>

# 请求一个不存在的 ID ,这将引发一个异常。
>>> Poll.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Poll matching query does not exist. Lookup parameters were {''id'': 2}

# 根据主键查询是常见的情况,因此 Django 提供了一个
# 主键精确查找的快捷方式。
# 以下代码等同于 Poll.objects.get(id=1).
>>> Poll.objects.get(pk=1)
<Poll: What''s up?>

# 确认我们自定义方法正常运行。
>>> p = Poll.objects.get(pk=1)
>>> p.was_published_recently()
True

# 给 Poll 设置一些 Choices 。通过 create 方法调用构造方法去创建一个新
# Choice 对象实例,执行 INSERT 语句后添加该 choice 到
# 可用的 choices 集中并返回这个新建的 Choice 对象实例。 Django 创建了
# 一个保存外键关联关系的集合 ( 例如 poll 的 choices) 以便可以通过 API
# 去访问。
>>> p = Poll.objects.get(pk=1)

# 从关联对象集中显示所有 choices  -- 到目前为止还没有。
>>> p.choice_set.all()
[]

# 创建三个 choices 。
>>> p.choice_set.create(choice_text=''Not much'', votes=0)
<Choice: Not much>
>>> p.choice_set.create(choice_text=''The sky'', votes=0)
<Choice: The sky>
>>> c = p.choice_set.create(choice_text=''Just hacking again'', votes=0)

# Choice 对象拥有访问它们关联的 Poll 对象的 API 。
>>> c.poll
<Poll: What''s up?>

# 反之亦然: Poll 对象也可访问 Choice 对象。
>>> p.choice_set.all()
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
>>> p.choice_set.count()
3

# 只要你需要 API 会自动连续关联。
# 使用双下划线来隔离关联。
# 只要你想要几层关联就可以有几层关联,没有限制。
# 寻找和今年发起的任何 poll 有关的所有 Choices
# ( 重用我们在上面建立的 ''current_year'' 变量 )。
>>> Choice.objects.filter(poll__pub_date__year=current_year)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]

# 让我们使用 delete() 删除 choices 中的一个。
>>> c = p.choice_set.filter(choice_text__startswith=''Just hacking'')
>>> c.delete()

欲了解更多有关模型关系的信息,请查看 访问关联对象 。欲了解更多有关如何使用双下划线来通过 API 执行字段查询的,请查看 字段查询 。 如需完整的数据库 API 信息,请查看我们的 数据库 API 参考 。

当你对 API 有所了解后, 请查看 教程 第2部分 来学习 Django 的自动生成的管理网站是如何工作的。

译者:Django 文档协作翻译小组,原文:Part 1: Models。

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留作者署名和文章出处。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

django 1.8 官方文档翻译: 1-2-2 编写你的第一个Django应用,第2部分

django 1.8 官方文档翻译: 1-2-2 编写你的第一个Django应用,第2部分

编写你的第一个 Django 程序 第2部分

本教程上接 教程 第1部分 。 我们将继续开发 Web-poll 应用,并且专注在 Django 的 自动生成的管理网站上。

哲理

为你的员工或客户生成添加、修改和删除内容的管理性网站是个单调乏味的工作。 出于这个原因,Django 根据模型完全自动化创建管理界面。

Django 是在新闻编辑室环境下编写的,“内容发表者”和“公共”网站之间有 非常明显的界线。网站管理员使用这个系统来添加新闻、事件、体育成绩等等, 而这些内容会在公共网站上显示出来。Django 解决了为网站管理员创建统一 的管理界面用以编辑内容的问题。

管理界面不是让网站访问者使用的。它是为网站管理员准备的。

启用管理网站

  • 默认情况下 Django 管理网站是不启用的 – 它是可选的。 要启用管理网站,需要做三件事:

  • 在 INSTALLED_APPS 设置中取消 "django.contrib.admin" 的注释。

  • 运行 python manage.py syncdb 命令。既然你添加了新应用到 INSTALLED_APPS 中,数据库表就需要更新。

  • 编辑你的 mysite/urls.py 文件并且将有关管理的行取消注释 – 共有三行取消了注释。该文件是 URLconf ;我们将在下一个教程中深入探讨 URLconfs 。现在,你需要知道的是它将 URL 映射到应用。最后你拥有的 urls.py 文件看起来像这样:

from django.conf.urls import patterns, include, url

# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('''',
    # Examples:
    # url(r''^$'', ''{{ project_name }}.views.home'', name=''home''),
    # url(r''^{{ project_name }}/'', include(''{{ project_name }}.foo.urls'')),

    # Uncomment the admin/doc line below to enable admin documentation:
    # url(r''^admin/doc/'', include(''django.contrib.admindocs.urls'')),

    # Uncomment the next line to enable the admin:
    url(r''^admin/'', include(admin.site.urls)),
)

( 粗体显示的行就是那些需要取消注释的行。)

启动开发服务器

让我们启动开发服务器并浏览管理网站。

回想下教程的第一部分,像如下所示启动你的开发服务器:

python manage.py runserver

现在,打开一个浏览器并在本地域名上访问 “/admin/” – 例如 http://127.0.0.1:8000/admin/ 。你将看到管理员的登录界面:

和你看到的不一样?

如果看到这,而不是上面的登录界面,那你应该得到一个类似如下所示的错误页面报告:

ImportError at /admin/ cannot import name patterns ...

那么你很可能使用的 Django 版本不符合本教程的版本。 你可以切换到对应的旧版本教程去或者更新到较新的 Django 版本。

进入管理网站

现在尝试登录进去。(还记得吗?在本教程的第一部分时你创建过一个超级用户的帐号。如果你没有创建或忘记了密码,你可以 另外创建一个 。) 你将看到 Djaong 的管理索引页:

你将看到一些可编辑的内容,包括 groups ,users 和 sites 。这些都是 Django 默认情况下自带的核心功能。

使 poll 应用的数据在管理网站中可编辑

但是 poll 应用在哪? 它可是没有在管理网站的首页上显示啊。

只需要做一件事:我们需要告诉管理网站 Poll 对象要有一个管理界面。为此,我们在你的 polls 目录下创建一个名为 admin.py 的文件,并添加如下内容::

from django.contrib import admin
from polls.models import Poll
admin.site.register(Poll)

你需要重启开发服务器才能看到变化。通常情况下,你每次修改过一个文件后开发 服务器都会自动载入,但是创建一个新文件却不会触发自动载入的逻辑。

探索管理功能

现在我们已经注册了 Poll ,那 Django 就知道了要在管理网站的首页上显示出来:

点击 “Polls” 。现在你在 polls 的 “更改列表” 页。该页 显示了数据库中所有的 polls 可让你选中一个进行编辑。 有个 “What’s up?” poll 是我们在第一个教程中创建的:

点击这个”What’s up?” 的 poll 进行编辑:

这有些注意事项:

  • 这的表单是根据 Poll 模型自动生成的。

  • 不同模型的字段类型 (DateTimeField, CharField) 会对应的相应的 HTML 输入控件。 每一种类型的字段 Djaong 管理网站都知道如何显示它们。

  • 每个 DateTimeField 都会有个方便的 JavaScript 快捷方式。日期有一个 “Today” 快捷方式和弹出式日历,而时间有个 “Now” 快捷方式和一个列出了常用时间选项的弹出式窗口。

在页面的底部还为你提供了几个选项:

  • Save – 保存更改并返回到当前类型的对象的更改列表页面。

  • Save and continue editing – 保存更改并重新载入当前对象的管理界面。

  • Save and add another – 保存更改并载入当前对象类型的新的空白表单。

  • Delete – 显示删除确认页。

如果 “Date published” 的值与你在第一部分教程时创建的 poll 的时间不符,这可能 意味着你忘记了将 TIME_ZONE 设置成正确的值了。修改正确后再重启载入页面 来检查值是否正确。

分别点击 “Today” 和 “Now” 快捷方式来修改 “Date published” 的值。 然后点击 “Save and continue editing” 。最后点击右上角的 “History” 。 你将看到一页列出了通过 Django 管理界面对此对象所做的全部更改的清单的页面, 包含有时间戳和修改人的姓名等信息:

自定义管理表单

花些时间感叹一下吧,你没写什么代码就拥有了这一切。通过 admin.site.register(Poll) 注册了 Poll 模型,Django 就能构造一个默认的 表单。通常情况下,你将要自定义管理表单的外观和功能。这样的话你就需要在注册对象 时告诉 Django 对应的配置。

让我们来看看如何在编辑表单上给字段重新排序。将 admin.site.register(Poll) 这行替换成::

class PollAdmin(admin.ModelAdmin):
    fields = [''pub_date'', ''question'']

admin.site.register(Poll, PollAdmin)

你将遵循这个模式 – 创建一个模型的管理对象,将它作为 admin.site.register() 方法的第二个参数传入 – 当你需要为一个对象做管理界面配置的时候。

上面那特定的更改使得 “Publication date” 字段在 “Question” 字段之前:

仅有两个字段不会令你印象深刻,但是对于有许多字段的管理表单时,选择一个直观 的排序方式是一个重要的实用细节。

刚才所说的有许多字段的表单,你可能想将表单中的字段分割成 fieldsets ::

class PollAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {''fields'': [''question'']}),
        (''Date information'', {''fields'': [''pub_date'']}),
    ]

admin.site.register(Poll, PollAdmin)

在 fieldsets 中每一个 tuple 的第一个元素就是 fieldset 的标题。 下面是我们表单现在的样子:

你可以为每个 fieldset 指定 THML 样式类。Django 提供了一个 "collapse" 样式类用于显示初始时是收缩的 fieldset 。 当你有一个包含一些不常用的长窗体时这是非常有用的

class PollAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {''fields'': [''question'']}),
        (''Date information'', {''fields'': [''pub_date''], ''classes'': [''collapse'']}),
    ]
Fieldset is initially collapsed

添加关联对象

Ok,现在我们有了 Poll 的管理页面。但是一个 Poll 拥有多个 Choices ,而 该管理页面并没有显示对应的 choices 。

是的。

我们有两种方法来解决这个问题。第一种就像刚才 Poll 那样在管理网站上 注册 Choice 。这很简单:

from polls.models import Choice

admin.site.register(Choice)

现在 “Choices” 在 Django 管理网站上是一个可用的选项了。”Add choice” 表单 看起来像这样:

该表单中,Poll 字段是一个包含了数据库中每个 poll 的选择框。 Django 知道 ForeignKey 在管理网站中以 <select> 框显示。在本例中,选择框中仅存在一个 poll 。

另外请注意 Poll 旁边的 “Add Another” 链接。每个有 ForeignKey 的对象关联到其他对象都会得到这个链接。 当点击 “Add Another” 时,你将会获得一个 “Add poll” 表单的弹出窗口。 如果你在窗口中添加了一 poll 并点击了 “Save” 按钮, Django 会将 poll 保存至数据库中并且动态的添加为你正在查看的 “Add choice” 表单中的 已选择项。

但是,这真是一个低效的将 Choice 对象添加进系统的方式。 如果在创建 Poll 对象时能够直接添加一批 Choices 那会更好。 让我们这样做吧。

移除对 Choice 模型的 register() 方法调用 。然后,将 Poll 的注册代码 编辑为如下所示:

from django.contrib import admin
from polls.models import Choice, Poll

class ChoiceInline(admin.StackedInline):
    model = Choice
    extra = 3

class PollAdmin(admin.ModelAdmin):
    fieldsets = [
        (None,               {''fields'': [''question'']}),
        (''Date information'', {''fields'': [''pub_date''], ''classes'': [''collapse'']}),
    ]
    inlines = [ChoiceInline]

admin.site.register(Poll, PollAdmin)

这将告诉 Django: “Choice 对象在 Poll 管理页面中被编辑。 默认情况下,提供 3 个 choices 的字段空间。

载入 “Add poll” 页面来看看,你可能需要重启你的开发服务器:

它看起来像这样:多了三个为关联 Choices 提供的输入插槽 – 由 extra 指定 – 并且每次你在 “Change” 页修改已经创建的对象时,都会另外获得三个额外插槽。

在现有的三个插槽的底部,你会发现一个 “Add another Choice” 链接。 如果你点击它,一个新的插槽会被添加。如果想移除添加的插槽, 你可以点击所添加的插槽的右上方的 X 。注意你不能移除原有的三个插槽。 此图片中显示了新增的插槽:

还有个小问题。为了显示所有关联 Choice 对象的字段需要占用大量的 屏幕空间。为此,Django 提供了一个以表格方式显示内嵌有关联对象的方式; 你只需要将 ChoiceInline 声明改为如下所示:

class ChoiceInline(admin.TabularInline):
    #...

使用了 TabularInline 后(而不是 StackedInline) ,基于表的格式下相关 对象被显示的更紧凑了:

需要注意的是有个额外的 “Delete?” 列允许保存时移除已保存过的行。

自定义管理界面的变更列表

现在 Poll 的管理界面看起来不错了,让我们给 “chang list” 页面做些调整 – 显示系统中所有 polls 的页面。

下面是现在的样子:

默认情况下, Django 显示的是每个对象 str() 的结果。但是若是我们能够 显示每个字段的话有时会更有帮助的。要做到这一点,需要使用 list_display 管理选项,这是一个 tuple ,包含了要显示的字段名, 将会以列的形式在该对象的 chang lsit 页上列出来::

class PollAdmin(admin.ModelAdmin):
    # ...
    list_display = (''question'', ''pub_date'')

效果再好的点话,让我们把在第一部分教程中自定义的方法 waspublishedrecently 也包括进来:

class PollAdmin(admin.ModelAdmin):
    # ...
    list_display = (''question'', ''pub_date'', ''was_published_recently'')

现在 poll 的变更列表页看起来像这样:

你可以点击列的标题对这些值进行排序 – 除了 waspublishedrecently 这一列,因为不支持根据方法输出的内容的排序。还要注意的是默认情况下列的标题是 waspublishedrecently ,就是方法名(将下划线替换为空格),并且每一行以字符串形式输出。

你可以通过给该方法 (在 models.py 内 ) 添加一些属性来改善显示效果,如下所示::

class Poll(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
    was_published_recently.admin_order_field = ''pub_date''
    was_published_recently.boolean = True
    was_published_recently.short_description = ''Published recently?''

再次编辑你的 admin.py 文件并添加一个改进 Poll 的 change list 页面效果的功能: 筛选 ( Filters ) 。在 PollAdmin 内添加一行如下所示的代码::

list_filter = [''pub_date'']

这就增加了一个 “筛选” 的侧边栏,让人们通过 pub_date 字段的值来筛选 change list 显示的内容:

显示筛选的类型取决于你需要筛选的字段类型。 因为 pub_date 是一个 DateTimeField 的实例,Django 知道提供对应的筛选选项:”Any date,” “Today,” “Past 7 days,” “This month,” “This year.”

为了效果更好。让我们来加上搜索功能::

search_fields = [''question'']

在 chang list 页的顶部增加了一个搜索框。当有人输入了搜索条件, Django 将搜索 question 字段。 虽然你可以使用任意数量的字段,如你希望的那样 – 但是因为它在后台用 LIKE 查询,为了保持数据库的性能请合理使用。

最后,因为 Poll 对象有日期字段,根据日期来向下钻取记录将会很方便。 添加下面这一行代码::

date_hierarchy = ''pub_date''

这会在 change list 页的顶部增加了基于日期的分层导航功能。 在最顶层,显示所有可用年份。然后可钻取到月份,最终到天。

现在又是一个好时机,请注意 change lists 页面提供了分页功能。默认情况下每一页显示 100 条记录。 Change-list 分页,搜索框,筛选,日期分层和列标题排序如你所原地在一起运行了。

自定义管理界面的外观

显而易见,在每一个管理页面顶部有 “Django administration” 是无语的。虽然它仅仅是个占位符。

不过使用 Django 的模板系统是很容易改变的。Django 管理网站有 Django 框架自身的功能,可以通过 Django 自身的模板系统来修改界面。

自定义你的 项目 模板

在你的项目目录下创建一个 templates 目录。模板可以放在你的文件系统的任何地方,Diango 都能访问。 (Django 能以任何用户身份在你的服务器上运行。) 然后,在你的项目中保存模板是一个好习惯。

默认情况下,TEMPLATE_DIRS 值是空的。因此,让我们添加一行代码,来告诉 Django 我们的模板在哪里::

TEMPLATE_DIRS = (
    ''/path/to/mysite/templates'', # 将此处改为你的目录。
)

现在从 Django 源代码中自带的默认 Django 管理模板的目录 (django/contrib/admin/templates) 下复制 admin/basesite.html 模板到你正在使用的 TEMPLATEDIRS 中任何目录的子目录 admin 下。例如:如果你的 TEMPLATEDIRS 中包含 ''/path/to/mysite/templates'' 目录, 如上所述,复制 django/contrib/admin/templates/admin/basesite.html 模板到 /path/to/mysite/templates/admin/base_site.html 。不要忘了是 admin 子目录。

Django 的源代码在哪里?

如果在你的文件系统中很难找到 Django 源代码,可以运行如下命令:

python -c "
import sys
sys.path = sys.path[1:]
import django
print(django.__path__)"

然后,只需要编辑该文件并将通用的 Djangot 文字替换为你认为适合的属于你自己的网站名。

该模板包含了大量的文字,比如 {% block branding %} 和 {{ title }}{% 和 {{ 标记是 Django 模板语言的一部分。 当 Django 呈现 admin/base_site.html 时,根据模板语言生成最终的 HTML 页面。 Don’t worry if you can’t make any sense of the template right now – 如果你现在不能理解模板的含义先不用担心 – 我们将在教程 3 中深入探讨 Django’ 的模板语言。

请注意 Django 默认的管理网站中的任何模板都是可覆盖的。 要覆盖一个模板,只需要像刚才处理 base_site.html 一样 – 从默认的目录下复制到你的自定义目录下,并修改它。

自定义你的 应用 模板

细心的读者会问:如果 TEMPLATE_DIRS 默认的情况下是空值, 那 Django 是如何找到默认的管理网站的模板的? 答案就是在默认情况下, Django 会自动在每一个应用的包内查找 templates/ 目录,作为备用使用。 (不要忘记 django.contrib.admin 是一个应用)。

我们的 poll 应用不是很复杂并不需要自定义管理模板。但是如果它变得更复杂 而且为了一些功能需要修改 Django 的标准管理模板,修改应用模板将是更 明智的选择,而不是修改项目模板。通过这种方式,你可以在任何新项目包括 polls 应用中自定义模板并且放心会找到需要的自定义的模板的。

有关 Django 怎样找到它的模板的更多信息,请参考 模板加载文档 。

自定义管理网站的首页

于此类似,你可能还想自定义 Django 管理网站的首页。

默认情况下,首页会显示在 INSTALLED_APPS 中所有注册了管理功能的应用, 并按字母排序。你可能想在页面布局上做大修改。总之,首页可能是管理网站中最重要的页面, 因此它应该很容易使用。

你需要自定义的模板是 admin/index.html 。 (同先前处理 admin/basesite.html 一样 – 从默认目录下复制到你自定义的模板目录下。) 编辑这个文件,你将看到一个名为 applist 的模板变量。这个变量包含了每一个 已安装的 Django 应用。你可以通过你认为最好的方法硬编码链接到特定对象的管理页面,而不是使用默认模板。 再次强调,如果你不能理解模板语言的话不用担心 – 我们将在教程 3 中详细介绍。

当你熟悉了管理网站的功能后,阅读 教程 第3部分 开始开发公共 poll 界面。

译者:Django 文档协作翻译小组,原文:Part 2: The admin site。

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留作者署名和文章出处。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

django 1.8 官方文档翻译: 1-2-3 编写你的第一个Django应用,第3部分

django 1.8 官方文档翻译: 1-2-3 编写你的第一个Django应用,第3部分

编写你的第一个 Django 程序 第3部分

本教程上接 教程 第2部分 。我们将继续 开发 Web-poll 应用并且专注在创建公共界面 – “视图 (views )”。

哲理

在 Django 应用程序中,视图是一“类”具有特定功能和模板的网页。 例如,在一个博客应用程序中,你可能会有以下视图:

  • 博客首页 – 显示最新发表的博客。

  • 博客详细页面 – 一篇博客的独立页面。

  • 基于年份的归档页 – 显示给定年份中发表博客的所有月份。

  • 基于月份的归档页 – 显示给定月份中发表博客的所有日期。

  • 基于日期的归档页 – 显示给定日期中发表的所有的博客。

  • 评论功能 – 为一篇给定博客发表评论。

在我们的 poll 应用程序中,将有以下四个视图:

  • Poll “index” 页 – 显示最新发布的民意调查。

  • Poll “detail” 页 – 显示一项民意调查的具体问题,不显示该项的投票结果但可以进行投票的 form 。

  • Poll “results” 页 – 显示一项给定的民意调查的投票结果。

  • 投票功能 – 为一项给定的民意调查处理投票选项。

在 Django 中,网页及其他内容是由视图来展现的。而每个视图就是一个简单的 Python 函数(或方法, 对于基于类的视图情况下)。Django 会通过检查所请求的 URL (确切地说是域名之后的那部分 URL)来匹配一个视图。

平时你上网的时候可能会遇到像 “ME2/Sites/dirmod.asp?sid=&type=gen&mod=Core+Pages&gid=A6CD4967199A42D9B65B1B” 这种如此美丽的 URL。 但是你会很高兴知道 Django 允许我们使用比那优雅的 URL 模式 来展现 URL。

URL 模式就是一个简单的一般形式的 URL - 比如: /newsarchive/<year>/<month>/.

Django 是通过 ‘URLconfs’ 从 URL 获取到视图的。而 URLconf 是将 URL 模式 ( 由正则表达式来描述的 ) 映射到视图的一种配置。

本教程中介绍了使用 URLconfs 的基本指令,你可以查阅 django.core.urlresolvers 来获取更多信息。

编写你的第一个视图

让我们编写第一个视图。打开文件 polls/views.py 并在其中输入以下 Python 代码

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world. You''re at the poll index.")

在 Django 中这可能是最简单的视图了。为了调用这个视图,我们需要将它映射到一个 URL – 为此我们需要配置一个URLconf 。

在 polls 目录下创建一个名为 urls.py 的 URLconf 文档。 你的应用目录现在看起来像这样

polls/
    __init__.py
    admin.py
    models.py
    tests.py
    urls.py
    views.py

在 polls/urls.py 文件中输入以下代码:

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('''',
    url(r''^$'', views.index, name=''index'')
)

下一步是将 polls.urls 模块指向 root URLconf 。在 mysite/urls.py 中插入一个 include() 方法,最后的样子如下所示

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('''',
    url(r''^polls/'', include(''polls.urls'')),
    url(r''^admin/'', include(admin.site.urls)),
)

现在你在 URLconf 中配置了 index 视图。通过浏览器访问 http://localhost:8000/polls/ ,如同你在 index 视图中定义的一样,你将看到 “Hello, world. You’re at the poll index.” 文字。

url() 函数有四个参数,两个必须的: regex 和 view, 两个可选的: kwargs, 以及 name。 接下来,来探讨下这些参数的意义。

url() 参数: regex

regex 是 regular expression 的简写,这是字符串中的模式匹配的一种语法, 在 Django 中就是是 url 匹配模式。 Django 将请求的 URL 从上至下依次匹配列表中的正则表达式,直到匹配到一个为止。

需要注意的是,这些正则表达式不会匹配 GET 和 POST 参数,以及域名。 例如:针对 http://www.example.com/myapp/ 这一请求,URLconf 将只查找 myapp/。而在 http://www.example.com/myapp/?page=3 中 URLconf 也仅查找 myapp/ 。

如果你需要正则表达式方面的帮助,请参阅 Wikipedia’s entry 和本文档中的 re 模块。 此外,O’Reilly 出版的由 Jeffrey Friedl 著的 “Mastering Regular Expressions” 也是不错的。 但是,实际上,你并不需要成为一个正则表达式的专家,仅仅需要知道如何捕获简单的模式。 事实上,复杂的正则表达式会降低查找性能,因此你不能完全依赖正则表达式的功能。

最后有个性能上的提示:这些正则表达式在 URLconf 模块第一次加载时会被编译。 因此它们速度超快 ( 像上面提到的那样只要查找的不是太复杂 )。

url() 参数: view

当 Django 匹配了一个正则表达式就会调用指定的视图功能,包含一个 HttpRequest 实例作为第一个参数和正则表达式 “捕获” 的一些值的作为其他参数。 如果使用简单的正则捕获,将按顺序位置传参数;如果按命名的正则捕获,将按关键字传参数值。 有关这一点我们会给出一个例子。

url() 参数: kwargs

任意关键字参数可传一个字典至目标视图。在本教程中,我们并不打算使用 Django 这一特性。

url() 参数: name

命名你的 URL ,让你在 Django 的其他地方明确地引用它,特别是在模板中。 这一强大的功能可允许你通过一个文件就可全局修改项目中的 URL 模式。

编写更多视图

现在让我们添加一些视图到 polls/views.py 中去。这些视图与之前的略有不同,因为 它们有一个参数::

def detail(request, poll_id):
    return HttpResponse("You''re looking at poll %s." % poll_id)

def results(request, poll_id):
    return HttpResponse("You''re looking at the results of poll %s." % poll_id)

def vote(request, poll_id):
    return HttpResponse("You''re voting on poll %s." % poll_id)

将新视图按如下所示的 url() 方法添加到 polls.urls 模块中去::

from django.conf.urls import patterns, url

from polls import views

urlpatterns = patterns('''',
    # ex: /polls/
    url(r''^$'', views.index, name=''index''),
    # ex: /polls/5/
    url(r''^(?P<poll_id>\d+)/$'', views.detail, name=''detail''),
    # ex: /polls/5/results/
    url(r''^(?P<poll_id>\d+)/results/$'', views.results, name=''results''),
    # ex: /polls/5/vote/
    url(r''^(?P<poll_id>\d+)/vote/$'', views.vote, name=''vote''),
)

在你的浏览器中访问 http://localhost:8000/polls/34/ 。将运行 detail() 方法并且显示你在 URL 中提供的任意 ID 。试着访问 http://localhost:8000/polls/34/results/ 和 http://localhost:8000/polls/34/vote/ – 将会显示对应的结果页及投票页。

当有人访问你的网站页面如 “ /polls/34/ ” 时,Django 会加载 mysite.urls 模块,这是因为 ROOT_URLCONF 设置指向它。接着在该模块中寻找名为urlpatterns 的变量并依次匹配其中的正则表达式。 include() 可让我们便利地引用其他 URLconfs 。请注意 include() 中的正则表达式没有 $ (字符串结尾的匹配符 match character) 而尾部是一个反斜杠。当 Django 解析 include() 时,它截取匹配的 URL 那部分而把剩余的字符串交由 加载进来的 URLconf 作进一步处理。

include() 背后隐藏的想法是使 URLs 即插即用。 由于 polls 在自己的 URLconf(polls/urls.py) 中,因此它们可以被放置在 “/polls/” 路径下,或 “/fun_polls/” 路径下,或 “/content/polls/” 路径下,或者其他根路径,而应用仍可以运行。

以下是当用户访问 “/polls/34/” 路径时系统中将发生的事:

  • Django 将寻找 ''^polls/'' 的匹配

  • 接着,Django 截取匹配文本 ("polls/") 后剩余的文本 – "34/" – 传递到 ‘polls.urls’ URLconf 中作进一步处理, 再将匹配 r''^(?P<poll_id>\d+)/$'' 的结果作为参数传给 detail() 视图

detail(request=<HttpRequest object>, poll_id=''34'')

pollid=''34'' 这部分就是来自 (?P<pollid>\d+) 匹配的结果。 使用括号包围一个 正则表达式所“捕获”的文本可作为一个参数传给视图函数;?P<poll_id> 将会定义名称用于标识匹配的内容; 而 \d+ 是一个用于匹配数字序列(即一个数字)的正则表达式。

因为 URL 模式是正则表达式,所以你可以毫无限制地使用它们。但是不要加上 URL 多余的部分如 .html – 除非你想,那你可以像下面这样::

(r''^polls/latest\.html$'', ''polls.views.index''),

真的,不要这样做。这很傻。

在视图中添加些实际的功能

每个视图只负责以下两件事中的一件:返回一个 HttpResponse 对象,其中包含了所请求页面的内容, 或者抛出一个异常,例如 Http404 。剩下的就由你来实现了。

你的视图可以读取数据库记录,或者不用。它可以使用一个模板系统,例如 Django 的 – 或者第三方的 Python 模板系统 – 或不用。它可以生成一个 PDF 文件,输出 XML , 即时创建 ZIP 文件, 你可以使用你想用的任何 Python 库来做你想做的任何事。

而 Django 只要求是一个 HttpResponse 或一个异常。

因为它很方便,那让我们来使用 Django 自己的数据库 API 吧, 在 教程 第1部分 中提过。修改下 index() 视图, 让它显示系统中最新发布的 5 个调查问题,以逗号分割并按发布日期排序::

from django.http import HttpResponse

from polls.models import Poll

def index(request):
    latest_poll_list = Poll.objects.order_by(''-pub_date'')[:5]
    output = '', ''.join([p.question for p in latest_poll_list])
    return HttpResponse(output)

在这就有了个问题,页面的设计是硬编码在视图中的。如果你想改变页面的外观,就必须修改这里的 Python 代码。因此,让我们使用 Django 的模板系统创建一个模板给视图用,就使页面设计从 Python 代码中 分离出来了。

首先,在 polls 目录下创建一个 templates 目录。 Django 将会在那寻找模板。

Django 的 TEMPLATELOADERS 配置中包含一个知道如何从各种来源导入模板的可调用的方法列表。 其中有一个默认值是 django.template.loaders.appdirectories.Loader ,Django 就会在每个 INSTALLEDAPPS 的 “templates” 子目录下查找模板 - 这就是 Django 知道怎么找到 polls 模板的原因,即使我们 没有修改 TEMPLATEDIRS, 还是如同在 教程 第2部分 那样。

组织模板

我们 能够 在一个大的模板目录下一起共用我们所有的模板,而且它们会运行得很好。 但是,此模板属于 polls 应用,因此与我们在上一个教程中创建的管理模板不同, 我们要把这个模板放在应用的模板目录 (polls/templates) 下而不是项目的模板目录 (templates) 。 我们将在 可重用的应用教程 中详细讨论我们 为什么 要这样做。

在你刚才创建的templates 目录下,另外创建个名为 polls 的目录,并在其中创建一个 index.html 文件。换句话说,你的模板应该是 polls/templates/polls/index.html 。由于知道如上所述的 app_directories 模板加载器是 如何运行的,你可以参考 Django 内的模板简单的作为 polls/index.html 模板。

模板命名空间

现在我们 也许 能够直接把我们的模板放在 polls/templates 目录下 ( 而不是另外创建 polls 子目录 ) , 但它实际上是一个坏注意。 Django 将会选择第一个找到的按名称匹配的模板, 如果你在 不同 应用中有相同的名称的模板,Django 将无法区分它们。 我们想要让 Django 指向正确的模板,最简单的方法是通过 命名空间 来确保是 他们的模板。也就是说,将模板放在 另一个 目录下并命名为应用本身的名称。

将以下代码添加到该模板中:

{% if latest_poll_list %}
    <ul>
    {% for poll in latest_poll_list %}
        <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

现在让我们在 index 视图中使用这个模板:

from django.http import HttpResponse
from django.template import Context, loader

from polls.models import Poll

def index(request):
    latest_poll_list = Poll.objects.order_by(''-pub_date'')[:5]
    template = loader.get_template(''polls/index.html'')
    context = Context({
        ''latest_poll_list'': latest_poll_list,
    })
    return HttpResponse(template.render(context))

代码将加载 polls/index.html 模板并传递一个 context 变量。 The context is a dictionary mapping template variable names to Python 该 context 变量是一个映射了 Python 对象到模板变量的字典。

在你的浏览器中加载 “/polls/” 页,你应该看到一个列表,包含了在教程 第1部分 中创建的 “What’s up” 调查。而链接指向 poll 的详细页面。

快捷方式: render()

这是一个非常常见的习惯用语,用于加载模板,填充上下文并返回一个含有模板渲染结果的 HttpResponse 对象。 Django 提供了一种快捷方式。这里重写完整的 index() 视图

from django.shortcuts import render

from polls.models import Poll

def index(request):
    latest_poll_list = Poll.objects.all().order_by(''-pub_date'')[:5]
    context = {''latest_poll_list'': latest_poll_list}
    return render(request, ''polls/index.html'', context)

请注意,一旦我们在所有视图中都这样做了,我们就不再需要导入 loader , Context 和 HttpResponse ( 如果你仍然保留了 detail,resutls, 和vote 方法,你还是需要保留 HttpResponse ) 。

render() 函数中第一个参数是 request 对象,第二个参数是一个模板名称,第三个是一个字典类型的可选参数。 它将返回一个包含有给定模板根据给定的上下文渲染结果的 HttpResponse 对象。

抛出 404 异常

现在让我们解决 poll 的详细视图 – 该页显示一个给定 poll 的详细问题。 视图代码如下所示::

from django.http import Http404
# ...
def detail(request, poll_id):
    try:
        poll = Poll.objects.get(pk=poll_id)
    except Poll.DoesNotExist:
        raise Http404
    return render(request, ''polls/detail.html'', {''poll'': poll})

在这有个新概念:如果请求的 poll 的 ID 不存在,该视图将抛出 Http404 异常。

我们稍后讨论如何设置 polls/detail.html 模板,若是你想快速运行上面的例子, 在模板文件中添加如下代码:

{{ poll }}

现在你可以运行了。

快捷方式: getobjector_404()

这很常见,当你使用 get() 获取对象时 对象却不存在时就会抛出 Http404 异常。对此 Django 提供了一个快捷操作。如下所示重写 detail() 视图:

from django.shortcuts import render, get_object_or_404
# ...
def detail(request, poll_id):
    poll = get_object_or_404(Poll, pk=poll_id)
    return render(request, ''polls/detail.html'', {''poll'': poll})

getobjector_404() 函数需要一个 Django 模型类作为第一个参数以及 一些关键字参数,它将这些参数传递给模型管理器中的 get() 函数。 若对象不存在时就抛出 Http404 异常。

哲理

为什么我们要使用一个 getobjector_404() 辅助函数 而不是在更高级别自动捕获 ObjectDoesNotExist 异常, 或者由模型 API 抛出 Http404 异常而不是 ObjectDoesNotExist 异常?

因为那样会使模型层与视图层耦合在一起。Django 最重要的设计目标之一 就是保持松耦合。一些控制耦合在 django.shortcuts 模块中介绍。

还有个 getlistor404() 函数,与 getobjector404() 一样 – 不过执行的是 filter() 而不是 get() 。若返回的是空列表将抛出 Http404 异常。

编写一个 404 ( 页面未找到 ) 视图

当你在视图中抛出 Http404 时,Django 将载入一个特定的视图来处理 404 错误。Django 会根据你的 root URLconf ( 仅在你的 root URLconf 中;在其他任何地方设置 handler404 都无效 )中设置的 handler404 变量来查找该视图,这个变量是个 Python 包格式字符串 – 和标准 URLconf 中的回调函数格式是一样的。 404 视图本身没有什么特殊性:它就是一个普通的视图。

通常你不必费心去编写 404 视图。若你没有设置 handler404 变量,默认情况下会使用内置的 django.views.defaults.pagenotfound() 视图。或者你可以在你的模板目录下的根目录中 创建一个 404.html 模板。当 DEBUG 值是 False ( 在你的 settings 模块中 ) 时, 默认的 404 视图将使用此模板来显示所有的 404 错误。 如果你创建了这个模板,至少添加些如“页面未找到” 的内容。

一些有关 404 视图需要注意的事项 :

  • 如果 DEBUG 设为 True ( 在你的 settings 模块里 ) 那么你的 404 视图将永远不会被使用 ( 因此 404.html 模板也将永远不会被渲染 ) 因为将要显示的是跟踪信息。

  • 当 Django 在 URLconf 中不能找到能匹配的正则表达式时 404 视图也将被调用。
    编写一个 500 ( 服务器错误 ) 视图

类似的,你可以在 root URLconf 中定义 handler500 变量,在服务器发生错误时 调用它指向的视图。服务器错误是指视图代码产生的运行时错误。

同样,你在模板根目录下创建一个 500.html 模板并且添加些像“出错了”的内容。

使用模板系统

回到我们 poll 应用的 detail() 视图中,指定 poll 变量后,polls/detail.html 模板可能看起来这样 :

<h1>{{ poll.question }}</h1>
<ul>
{% for choice in poll.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

模板系统使用了“变量.属性”的语法访问变量的属性值。 例如 {{ poll.question }} , 首先 Django 对 poll 对象做字典查询。 否则 Django 会尝试属性查询 – 在本例中属性查询成功了。 如果属性查询还是失败了,Django 将尝试 list-index 查询。

在 {% for %} 循环中有方法调用: poll.choiceset.all 就是 Python 代码 poll.choiceset.all(),它将返回一组可迭代的 Choice 对象,可以用在 {% for %} 标签中。

请参阅 模板指南 来了解模板的更多内容。

移除模板中硬编码的 URLS

记得吗? 在 polls/index.html 模板中,我们链接到 poll 的链接是硬编码成这样子的:

<li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>

问题出在硬编码,紧耦合使得在大量的模板中修改 URLs 成为富有挑战性的项目。 不过,既然你在 polls.urls 模块中的 url() 函数中定义了 命名参数,那么就可以在 url 配置中使用 {% url %} 模板标记来移除特定的 URL 路径依赖:

<li><a href="{% url ''detail'' poll.id %}">{{ poll.question }}</a></li>

Note

如果 {% url ''detail'' poll.id %} (含引号) 不能运行,但是 {% url detail poll.id %} (不含引号) 却能运行,那么意味着你使用的 Djang 低于 < 1.5 版。这样的话,你需要在模板文件的顶部添加如下的声明::

{% load url from future %}

其原理就是在 polls.urls 模块中寻找指定的 URL 定义。 你知道命名为 ‘detail’ 的 URL 就如下所示那样定义的一样::

...
# ''name'' 的值由 {% url %} 模板标记来引用
url(r''^(?P<poll_id>\d+)/$'', views.detail, name=''detail''),
...

如果你想将 polls 的 detail 视图的 URL 改成其他样子,或许像 polls/specifics/12/ 这样子,那就不需要在模板(或者模板集)中修改而只要在 polls/urls.py 修改就行了:

...
# 新增 ''specifics''
url(r''^specifics/(?P<poll_id>\d+)/$'', views.detail, name=''detail''),
...

URL 名称的命名空间

本教程中的项目只有一个应用:polls 。在实际的 Django 项目中,可能有 5、10、20 或者 更多的应用。Django 是如何区分它们的 URL 名称的呢?比如说,polls 应用有一个 detail 视图,而可能会在同一个项目中是一个博客应用的视图。Django 是如何知道 使用 {% url %} 模板标记创建应用的 url 时选择正确呢?

答案是在你的 root URLconf 配置中添加命名空间。在 mysite/urls.py 文件 (项目的 urls.py,不是应用的) 中,修改为包含命名空间的定义:

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('''',
    url(r''^polls/'', include(''polls.urls'', namespace="polls")),
    url(r''^admin/'', include(admin.site.urls)),
)

现在将你的 polls/index.html 模板中原来的 detail 视图:

<li><a href="{% url ''detail'' poll.id %}">{{ poll.question }}</a></li>

修改为包含命名空间的 detail 视图:

<li><a href="{% url ''polls:detail'' poll.id %}">{{ poll.question }}</a></li>

当你编写视图熟练后,请阅读 教程 第4部分 来学习如何处理简单的表单和通用视图。

译者:Django 文档协作翻译小组,原文:Part 3: Views and templates。

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留作者署名和文章出处。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

django 1.8 官方文档翻译: 1-2-4 编写你的第一个Django应用,第4部分

django 1.8 官方文档翻译: 1-2-4 编写你的第一个Django应用,第4部分

编写你的第一个 Django 程序 第4部分

本教程上接 教程 第3部分 。我们将 继续开发 Web-poll 应用并且关注在处理简单的窗体和优化我们的代码。

编写一个简单的窗体

让我们把在上一篇教程中编写的 poll 的 detail 模板更新下,在模板中包含 HTML 的 <form> 组件:

<h1>{{ poll.question }}</h1>

{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}

<form action="{% url ''polls:vote'' poll.id %}" method="post">
{% csrf_token %}
{% for choice in poll.choice_set.all %}
    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
    <label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br />
{% endfor %}
<input type="submit" value="Vote" />
</form>

简单的总结下:

  • 上面的模板中为每个投票选项设置了一个单选按钮。每个单选按钮的 value 是投票选项对应的 ID 。每个单选按钮的 name 都是 “choice”。这意味着,当有人选择了一个单选按钮并提交了表单,将会发送 的 POST 数据是 choice=3。这是 HTML 表单中的基本概念。

  • 我们将 form 的 action 设置为 {% url ''polls:vote'' poll.id %},以及设置了 method="post" 。使用 method="post" ( 而不是 method="get") 是非常重要的,因为这种提交表单的方式会改变服务器端的数据。 当你创建一个表单为了修改服务器端的数据时,请使用 method="post" 。这不是 Django 特定的技巧;这是优秀的 Web 开发实践。

  • forloop.counter 表示 for 标签在循环中已经循环过的次数

  • 由于我们要创建一个POST form ( 具有修改数据的功能 ),我们需要担心跨站点请求伪造 ( Cross Site Request Forgeries )。 值得庆幸的是,你不必太担心这一点,因为 Django 自带了一个非常容易使用的系统来防御它。 总之,所有的 POST form 针对内部的 URLs 时都应该使用 {% csrf_token %} 模板标签。

现在,让我们来创建一个 Django 视图来处理提交的数据。 记得吗?在 教程 第3部分 中,我们为 polls 应用创建了一个 URLconf 配置中包含有这一行代码:

url(r''^(?P<poll_id>\d+)/vote/$'', views.vote, name=''vote''),

我们还创建了一个虚拟实现的 vote() 函数。让我们创建一个真实版本吧。在 polls/views.py 中添加如下代码:

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from polls.models import Choice, Poll
# ...
def vote(request, poll_id):
    p = get_object_or_404(Poll, pk=poll_id)
    try:
        selected_choice = p.choice_set.get(pk=request.POST[''choice''])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the poll voting form.
        return render(request, ''polls/detail.html'', {
            ''poll'': p,
            ''error_message'': "You didn''t select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse(''polls:results'', args=(p.id,)))

在这代码中有些内容还未在本教程中提到过:

request.POST 是一个类似字典的对象,可以让你 通过关键字名称来获取提交的数据。在本例中, request.POST[''choice''] 返回了所选择的投票项目的 ID ,以字符串的形式。 request.POST 的值永远是字符串形式的。

请注意 Django 也同样的提供了通过 request.GET 获取 GET 数据的方法 – 但是在代码中我们明确的使用了 request.POST 方法,以确保数据是通过 POST 方法来修改的。

如果 choice 未在 POST 数据中提供 request.POST[''choice''] 将抛出 KeyError 当未给定 choice 对象时上面的代码若检测到抛出的是 KeyError 异常就会向 poll 显示一条错误信息。

在增加了投票选项的统计数后,代码返回一个 HttpResponseRedirect 对象而不是常见的 HttpResponse 对象。 HttpResponseRedirect 对象需要一个参数:用户将被重定向的 URL (请继续看下去在这情况下我们是如何构造 URL ) 。

就像上面用 Python 作的注释那样,当成功的处理了 POST 数据后你应该总是返回一个 HttpResponseRedirect 对象。 这个技巧不是特定于 Django 的;它是优秀的 Web 开发实践。

在本例中,我们在 HttpResponseRedirect 的构造方法中使用了 reverse() 函数。 此函数有助于避免在视图中硬编码 URL 的功能。它指定了我们想要的跳转的视图函数名以及视图函数中 URL 模式相应的可变参数。在本例中,我们使用了教程 第3部分中的 URLconf 配置, reverse() 将会返回类似如下所示的字符串

''/polls/3/results/''

... 在此 3 就是 p.id 的值。该重定向 URL 会调用 ''results'' 视图并显示最终页面。

正如在教程 第3部分提到的,request 是一个 HttpRequest 对象。想了解 HttpRequest 对象更多的内容,请参阅 request 和 response 文档 。

当有人投票后,vote() 视图会重定向到投票结果页。让我们来编写这个视图

def results(request, poll_id):
    poll = get_object_or_404(Poll, pk=poll_id)
    return render(request, ''polls/results.html'', {''poll'': poll})

这几乎和 教程 第3部分 中的 detail() 视图完全一样。 唯一的区别就是模板名称。 稍后我们会解决这个冗余问题。

现在,创建一个 polls/results.html 模板:

<h1>{{ poll.question }}</h1>

<ul>
{% for choice in poll.choice_set.all %}
    <li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul>

<a href="{% url ''polls:detail'' poll.id %}">Vote again?</a>

现在,在浏览器中访问 /polls/1/ 并完成投票。每次投票后你将会看到结果页数据都有更新。 如果你没有选择投票选项就提交了,将会看到错误的信息。

使用通用视图:优化代码

detail() ( 在 教程 第3部分 中) 和 results() 视图 都很简单 – 并且还有上面所提到的冗余问题。index() 用于显示 polls 列表的 index() 视图 (也在教程 第3部分中),也是存在类似的问题。

这些视图代表了基本的 Web 开发中一种常见的问题: 根据 URL 中的参数从数据库中获取数据,加载模板并返回渲染后的内容。由于这类现象很 常见,因此 Django 提供了一种快捷方式,被称之为“通用视图”系统。

通用视图抽象了常见的模式,以至于你不需要编写 Python 代码来编写一个应用。

让我们把 poll 应用修改成使用通用视图系统的应用,这样我们就能删除删除一些我们自己的代码了。 我们将采取以下步骤来进行修改:

  • 修改 URLconf 。

  • 删除一些旧的,不必要的视图。

  • 修正 URL 处理到对应的新视图。

请继续阅读了解详细的信息。

为什么要重构代码?

通常情况下,当你编写一个 Django 应用时,你会评估下通用视图是否适合解决你的问题, 如果适合你就应该从一开始就使用它,而不是进行到一半才重构你的代码。 但是本教程直到现在都故意集中介绍“硬编码”视图,是为了专注于核心概念上。

就像你在使用计算器前需要知道基本的数学知识一样。

修改 URLconf

首先,打开 polls/urls.py 的 URLconf 配置文件并修改成如下所示样子

from django.conf.urls import patterns, url
from django.views.generic import DetailView, ListView
from polls.models import Poll

urlpatterns = patterns('''',
    url(r''^$'',
        ListView.as_view(
            queryset=Poll.objects.order_by(''-pub_date'')[:5],
            context_object_name=''latest_poll_list'',
            template_name=''polls/index.html''),
        name=''index''),
    url(r''^(?P<pk>\d+)/$'',
        DetailView.as_view(
            model=Poll,
            template_name=''polls/detail.html''),
        name=''detail''),
    url(r''^(?P<pk>\d+)/results/$'',
        DetailView.as_view(
            model=Poll,
            template_name=''polls/results.html''),
        name=''results''),
    url(r''^(?P<poll_id>\d+)/vote/$'', ''polls.views.vote'', name=''vote''),
)

修改 views

在这我们将使用两个通用视图: ListView 和 DetailView 。这两个视图分别用于显示两种抽象概念 “显示一系列对象的列表” 和 “显示一个特定类型的对象的详细信息页”。

  • 每个视图都需要知道使用哪个模型数据。因此需要提供将要使用的 model 参数。

  • DetailView 通用视图期望从 URL 中捕获名为 "pk" 的主键值,因此我们将 poll_id 改为 pk 。

默认情况下, DetailView 通用视图使用名为 <应用名>/<模型名>detail.html 的模板。在我们的例子中,将使用名为 "polls/polldetail.html" 的模板。 templatename 参数是告诉 Django 使用指定的模板名,而不是使用自动生成的默认模板名。 我们也指定了 results 列表视图的 templatename – 这确保了 results 视图和 detail 视图渲染时会有不同的外观,虽然它们有一个 DetailView 隐藏在幕后。

同样的,~django.views.generic.list.ListView 通用视图使用的默认模板名为 <应用名>/<模型名>list.html ;我们指定了 templatename 参数告诉 ListView 使用已经存在的 "polls/index.html" 模板。

在之前的教程中,模板提供的上下文中包含了 poll 和 latestpolllist 上下文变量。在 DetailView 中 poll 变量是自动提供的 – 因为我们使用了一个 Django 模型 (Poll) ,Django 能够为上下文变量确定适合的名称。 另外 ListView 自动生成的上下文变量名是 polllist 。若要覆盖此变量我们需要提供 contextobjectname 选项, 我们想要使用 latestpoll_list 来替代它。作为一种替代方式,你可以改变你的模板来 匹配新的默认的上下文变量 – 但它是一个非常容易地告诉 Django 使用你想要的变量的方式。

现在你可以在 polls/views.py 中删除 index() , detail() 和 results() 视图了。 我们不需要它们了 – 它们已替换为通用视图了。你也可以删除不再需要的 HttpResponse 导入包了。

运行服务器,并且使用下基于通用视图的新投票应用。

有关通用视图的完整详细信息,请参阅 通用视图文档.

当你熟悉了窗体和通用视图后,请阅读 教程 第5部分 来学习测试我们的投票应用。

译者:Django 文档协作翻译小组,原文:Part 4: Forms and generic views。

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留作者署名和文章出处。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

我们今天的关于搭建你的第一个Django应用程序简述搭建django开发环境所需要的步骤的分享已经告一段落,感谢您的关注,如果您想了解更多关于django 1.8 官方文档翻译: 1-2-1 编写你的第一个Django应用,第1部分、django 1.8 官方文档翻译: 1-2-2 编写你的第一个Django应用,第2部分、django 1.8 官方文档翻译: 1-2-3 编写你的第一个Django应用,第3部分、django 1.8 官方文档翻译: 1-2-4 编写你的第一个Django应用,第4部分的相关信息,请在本站查询。

本文标签: