我们继续教程1的部分开始。我们将要建立数据库,创建你的第一个模型,并且快速简介django的自动生成后台管理系统。
数据库设置
现在,打开mysite/settings.py。这是一个常规的模块级别的变量来表示django设置的python模块。
默认情况,配置使用的是SQLite。如果你是一个数据库方面的新手,或者只是对使用django感兴趣,这是最简单的选择。SQLite被包含在Python中,所以你不必再进行任何安装来支持数据库。当开始一个真正的项目时,你可能想使用扩展性更好的数据库,以避免开发过程中数据库切换的痛苦,例如PostgreSQL。
如果你想用其他的数据库,安装适当的database bindings,并且修改数据库中’default‘项来匹配你的数据库连接设置:
- ENGINE,可以是'django.db.backends.sqlite3', 'django.db.backends.postgresql', 'django.db.backends.mysql', or 'django.db.backends.oracle',其他也是可以的,请看 also available。
- NAME,数据库的名字,如果你使用的是SQLite,数据库就是你的电脑上的一个文件,既然这样,NAME应该是绝对路径,并包括文件名。默认值os.path.join(BASE_DIR, 'db.sqlite3'),将会把文件存储在你的项目目录下。
如果你没有使用SQLite作为你的数据库,要添加USER,PASSWORD,HOST项配置。更多细节请参考文档DATABASES
。
除了SQLite意外的数据库
如果你使用除了SQLite以外的数据库,请确保你已经创建了数据库。可以在你的数据库可交互命令行中,使用命令“CREATE DATABASE database_name;”。
还要确保数据库用户在mysite/settings.py中提供了“创建数据库”的权限。在稍后的教程中,这将允许自动生成一个test数据库。
如果你使用SQLite,你不必创建任何东西,当它被需要时会自动创建。
当你编辑mysite/settings.py时,设置TIME_ZONE为你所在的时区。
同时还要注意,在文件上方的INSTALL_APP设置,这里控制了django实例的应用的所有名字。应用可以被用在多个项目中,其他人可以通过打包和部署它们在他人的项目中。
默认情况下,INSTALL_APP包含了下面的应用,所有都是django创建的:
-
django.contrib.admin
:后台管理网站,稍后你就会用到它。 -
django.contrib.auth
:一个身份验证系统。 -
django.contrib.contenttypes
:一个内容类型的框架。 -
django.contrib.sessions
:一个session框架。 -
django.contrib.messages
:一个消息框架。 -
django.contrib.staticfiles
:一个管理静态文件的框架。
常见情况下,这些应用都会被包含在内。
这些应用中的一些需要至少一张数据库表才能使用,所以,我们需要先在数据库中创建表,然后再使用它们。为了达到目的,我们先运行下面的命令:
$ python manage.py migrate
migrate命令关注着INSTALL_APP的设置,根据mysite/settings.py数据库的设置来创建了一切必须的数据库表,数据迁移会随着应用进行装载。你可以看到每条数据库迁移记录。如果你对此感兴趣,运行你的数据库命令行,输入\dt (PostgreSQL), SHOW TABLES; (MySQL), .schema (SQLite), or SELECT TABLE_NAME FROM USER_TABLES; (Oracle) 用来展示django创建的表。
最小的应用
就像上面我们提到的,一般情况都是包含这些默认应用的,但是,并不是所有人都需要它们,如果你不需要它们,可以注释或者适当的删除INSTALL_APP中的某一行在运行数据库迁移命令之前。migrate命令只会迁移INSTALL_APP中的应用程序。
创建模型
现在我们将定义你的模型,实际上是用额外添加的元数据布局你的数据库。
哲学
模型是单一的,它定义了你的数据真实的数据源,包含了基本的字段和数据行为。Django遵循DRY原则(DRY Principle
)。目标是在一处定义数据模型,并且可以自动从它里面派生子类。
这包含了数据迁移,不像ruby on rails,例如,数据迁移是完全派生自你的数据模型文件,本质上是历史记录,Django可以通过update数据库事件回滚来匹配你的当前模型。
在我们的投票应用中,我们将创建两个模型:Question和Choise。Question有两个字段question和publication date。Choise有两个字段:文本字段choise和投票记录字段。每个Choise都关联到一个Question。
这些概念都有简单的Python类来表示。编辑polls/models.py文件,就像下面这样:
代码意思很明显。每个模型都由类django.db.models.Model的子类来表示,每个模型都由若干个类变量,用来表示模型中的数据库字段。
每个字段都由Field类的实例来表示-比如CharField表示字符字段,DateTimeField表示时间字段。这会告诉Django每个字段应该保存为什么数据类型。
每个Field实例的名字就是字段的名字(例如,question_text或者pub_date),这是对机器友好的方式。你将会在你的python代码中使用这些值,并且你的数据库将会用它做列名。
你能使用一个可选的第一个位置参数来设计一个可读性高的名字,这将会用于Django的自省功能,它将作为文档被替换。如果这个字段没有被提供,Django将使用对机器友好的名字。在这个例子中,我们只会对Question.pub_date定义可读性高的名字设置。这个模型的其他字段,将以机器友好的方式设置,因为这足以满足人类的可读性要求。
一些Field类需要必须的参数。CharField,例如,需要你传递一个max_length参数。不仅用于数据库模式,也会在验证中使用,我们稍后会看到。
一个Field可以有不同的可选参数,在这种情况下,我们将把votes字段的default属性设为0。
最后,注意关系的定义,要使用ForeignKey。这会告诉Django每个Choise被关联到一个Question。Django支持所有常见的数据库关系:多对一,多对多,一对一。
激活模型
这些一小段代码给予Django很多信息。随之,Django会这样做:
- 为这个应用创建一个数据库模式(CREATE TABLE statements)
- 创建一个访问Question和Choise对象的python API
但是,我们首先应该告诉项目polls应用已经被安装了。
哲学
Django应用是“可插拔式”的:你可以将一个应用用于多个项目中,并且可以分布式应用,因为他们不必绑定到Django上安装。
为了在我们的项目中包含应用,我们需要参考配置类中的INSTALL_APPS。PollsConfig类在polls/apps.py文件中,所以,它的点路径是'polls.apps.PollsConfig'。编辑mysite/settings.py文件,添加点路径到INSTALL_APPS设置中,看起来是这样的:
现在Django知道已经包含了polls应用了,让我们运行一条命令:
$ python manage.py makemigrations polls
你将会看到类似如下的显示:
通过运行makemigrations,你是在告诉Django,你更改了模型文件,并且你希望这些改变作为一次数据迁移被存储。
Migrations是Django存储你改变模型的记录(并且影响你的数据库模式)-他们仅仅是磁盘上的文件。如果你喜欢,可以阅读你模型的迁移记录,比如polls/migrations/0001_initial.py文件。不必担心,你不必每次Django生成时都阅读它们,它们设置为可以人为编辑的,目的是让你可以手动更改Django的改动。
这有一个命令将会为你运行数据迁移,并且自动管理你的数据库模式,它叫migrate,我们稍后就会接触到它。但是首先,让门看看migration运行了什么SQL。sqlmigrate命令加上数据迁移的名字就能返回执行了什么SQL。
$ python manage.py sqlmigrate polls 0001
你应该看到类似下面的输出(为了提高可读性,我们进行了格式化):
注意下面的事项:
- 下面确切的输出会取决于你使用的数据库,上面的输出是PostgreSQL的。
- 表名是根据应用的名字自动生成的,就是模块的名字的小写-question和choise。(你可以重写这个特性)
- 主键(IDs)是自动添加的(这个特性同样可以重写)
- 依照惯例,Django添加了'_id'外键字段(同样可以重写)
- 外键关系是由FOREIGN KEY限制的。不用担心DEFERRABLE部分,那仅仅是告诉postgreSQL不要在事务的末尾强制执行。
- 为你的数据库量身定制,明确数据库的字段类型,例如auto_increment(MySQL),serial(PostgreSQL),或者integer primary key autoincrement(SQLite)会自动处理,同样适用于字段名,例如,适用单引号或者双引号。
- sqlmigrate命令并没有实际地对数据库进行数据迁移,它仅仅是打印到屏幕上,目的是让你知道执行了什么SQL,Django认为这是必须的。这对查看django即将要做什么操作是很有用的,在数据库管理员要查看SQL脚本时。
如果你感兴趣,你可以运行python manage.py check,这会检查项目中的问题,并不会做数据迁移,也不会涉及到数据库:
$ python manage.py migrate
migrate命令会获取所有的未被应用的数据迁移信息(Django会在你的数据库中用一个叫’django_migrations‘的表来记录哪些数据迁移记录被应用了),并在数据库上运行-本质上来讲,你修改模型的时候会同步修改数据库模式。
Migrations是非常有用的,让你可以在开发项目时随着时间改变模型,而不用删除原有的表再次新建表-它专注于动态更新数据库,在不丢失数据的情况下。在之后的教程部分,我们会更深层次的封装他们,但是现在,记住三步来指导你修改模型:
- 修改模型(在models.py文件中)
- 运行python manage.py makemigrations来为这些改变创建迁移记录
- 运行python manage.py migrate来应用这些改变到数据库上。
把创建迁移记录和应用迁移记录命令分开的原因是因为,你需要提交migration到你的版本控制系统,并装载到你的应用程序上,这不仅仅让你的开发更简单,也让其他开发者更有用。
阅读 django-admin documentation来查看manage.py能做的全部信息。
使用API
现在,让我们打开python shell来使用django给你提供的免费API。激活python shell,使用下面的命令:
$ python manage.py shell
我们使用这个命令来代替简单的"python",因为manage.py设置了DJANGO_SETTINGS_MODULE环境变量,会把Django和python的路径导入到mysite/settings.py文件中。
一旦你进入到shell中,浏览 database API。
等一下,<Question: Question object (1)>不是对象的有用的表达方式。让我们通过修改Question模型修复这个问题(在polls/models.py文件中),并且在Question和Choise中都添加一个str()方法。
添加str()方法对你的模型来说很重要,不仅仅是在处理时出现提示符以给你自己提供方便,更因为对象的表达形式会被django自动生成管理。
注意这些都是普通的python方法,为了示范,让我们自定义一个方法。
注意添加的import datetime和from django.utils import timezone,引用了python的标准库中的datetime模块,并且Django的时区相关的工具在django.utils.timezone中,如果你对Python中的处理时区问题不太熟悉,你可以在 time zone support docs了解更多。
保存这些改变,打开一个新的python shell,再次运行python manage.py shell。
想了解更多关于模型关系的信息,可以看 Accessing related objects。查看怎样使用双下划线执行字段通过API查找,可以看Field lookups。更多数据库API的详细信息,可以看 Database API reference。
介绍Django Admin
哲学
为你的员工或者客户生成后台管理系统,来进行添加,删除,修改内容是冗长乏味且缺乏创造性的工作。为此,Django完全自动模型的管理界面。
Django诞生于报社,非常清楚的分离了“发布内容”和“公共”网站。网站管理者使用系统来添加新闻故事,事件,体育消息等等,这些内容都是在“公共”网站上的。Django解决了管理网站和编辑内容都在同一个网站界面的问题。
Admin不打算让客户访问,它是网站管理者使用的。
创建一个管理员用户
首先,我们得创建一个可以访问admin网站的用户,运行如下命令:
$ python manage.py createsuperuser
输入你期望的用户名,然后按回车:
Username: admin
然后会提示你输入你期望的邮箱地址:
Eamil Address: admin@example.com
下一步是输入你的密码,你需要输入两次,第二次输入是为了确认是否和第一次相同。
Password: ******
Password(again): *****
Superuser created succesfully.
启动开发服务器
Django的后台管理系统默认是被激活了的,让我们启动开发者服务器,并在浏览器中查看。
如果服务器没有启动,可以这样做:
$ python manage.py runserver
现在打开浏览器,跳到本地域名的'/admin/'路径下,例如 http://127.0.0.1:8000/admin/,你应该在屏幕上看到用户登录的页面:
translation默认是被开启了的。登录页面也许会展示你所使用的语言,这取决于你的浏览器的设置,以及Django是否翻译了这门语言。
你应该看到了几种可编辑的内容:groups和users。是django.contrib.auth提供的,验证框架由Django进行装载。
让polls应用可以在admin中被编辑
但是我们的poll应用在哪呢?它没有显示在admin的首页。
我们只需要做一件事:我们需要告诉admin,Question对象有一个管理界面。为了达到目的,打开polls/models.py文件,并编辑它:
浏览功能不受限的admin
现在我们注册了Question,Django知道应该把它展示在首页上了:
点击“Question”,现在你就进入到了question的“change list”页面了。这个页面会展示数据库中所有的question对象的列表,让你可以选择一个并改变它。
点击“what’s up”,询问是否更改。
这有一些问题需要注意:
- 这个表单是Question模型自动生成的
- 不同类型的模型字段(DateTimeField,CharField)根据适当的HTML输入。每个字段在admin中都知道如何展示。
- 每个DateTimeField不收js的束缚,日期获取“今天”并在日历中弹出,并获取今天的日期,便捷的弹出当前可用列表。
下面的部分给你几个选项:
- Save-保存更改,返回这个类型对象的“change-list”页面
- Save and continue editing- 保存更改,并重新加载这个对象的管理页面
- Save and add another-保存更改,新建一个这个对象的空表单。
- Delete-展示一个确认删除的页面
如果"Date Pulisher"的值和你在教程1中创建的时间不匹配时,这可能意味着你没有正确的设置时区”TIME_ZONE”,修改它,刷新页面,返现正确的值出现了。
修改“Date publisher”通过点击"Today"和"now"标签,然后再点击"Save and continue editing"。然后点击右上方的"history"。你会看到通过django admin进行所有改动的页面,有时间戳,用户名(谁修改的):
当你了解了模型的API时,并熟悉了django admin时,请阅读 part 3 of this tutorial来学习如何给polls应用添加更多的视图。