Django官方手册--2

编写你的第一个Django App,第二章

本教程在第一章结束后。我们开始设计数据库,创建你的第一个model,以及获取一个Django自动创建管理网站的简单介绍。

数据库设置

现在打开文件mysite/settings.py。这是一个普通的python模块,用模块级别变量来表示Django设置。
默认情况下,配置使用SQLite。如果你是一个数据库新手,或者你只是对Django感兴趣,这是最简单的选择。
SQLite被包含在Python中,所以你不需要安装任何东西来支持你的数据库。当你开始第一个真正的项目时,你可能想使用更具扩展性的数据库,比如PostgreSQL,来避免切换数据库的痛苦。
如果你希望使用其他数据库,安装适合的 database bindings ,并改变 DATABASES中defualt键的值来匹配你的数据库连接设置:

  • 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作为你的数据库,需要添加设置,比如USERPASSWORDHOST是必须被添加的。更多细节,请看参考文档DATABASES

除了SQLite之外的数据库

如果你正在使用SQLite之外的数据库,确保你已经创建了一个数据库。在数据库的交互提示中使用:"CREATE DATABASE database_name;"。
同时也要确保数据库使用者拥有在 mysite/settings.py中“create database”的权限。这将允许自动创建一个 test database,将以后的教程中用到。
如果你使用SQLite,你不需要预先创建任何东西——数据库文件将会在需要的时候被创建。

如果你正在编辑mysite/settings.py这个文件,把TIME_ZONE设置为你的时区。
与此同时也要注意,把 INSTALLED_APPS
设置在文件的顶部。它包含了在Django实例中,所有被激活的Django应用程序的名字。应用程序可以被用于多个项目中,并且你可以打包或者分解它们,供其他项目的人员使用。
默认情况下, INSTALLED_APPS包含了下面这些应用程序,这些程序都是Django的:

$ python manage.py migrate

migrate命令在INSTALLED_APPS设置中搜索,并根据mysite/settings.py文件中的数据库设置创建任何必须的数据表,数据库迁移附带应用。你可以看到它迁移的每一条记录。如果你感兴趣,运行数据库的命令行客户端,并且输入\dt (PostgreSQL), SHOW TABLES; (MySQL), .schema (SQLite), or SELECT TABLE_NAME FROM USER_TABLES; (Oracle)来展示Django创建的数据表。

极简主义者

就像我们上面说过的,默认情况下上述的应用程序都包含在普通案例中,但是,并不是每个人都需要它们。如果你不需要它们中的任意一个或者全部都不需要,可以随意的注释掉,或者在运行migrate命令之前从 INSTALLED_APPS中删除。 migrate命令将仅仅执行INSTALLED_APPS中应用程序的迁移。

创建models

现在,我们将定义model——实际上,你的数据库布局,带有附加的元数据。

基本原理

模型是唯一的,决定了你的数据的权威性来源。它包含了基本的字段和你存储的数据的行为。Django遵循了 DRY Principle。目的是在一个地方定义你的数据模型,并且从这个地方自动派生出一些东西。
这包括了迁移——不同于Ruby,例如,迁移是彻底地和你的模型文件分离,并且本质上是一种历史,Django可以通过更新你的数据库计划来匹配当前模型。

在我们的简单投票应用程序中,我们将会创建两个model:Question和Choice。Question模型有一个question字段和一个出版日期字段。Choice有两个字段:选择的文本和投票结果。每个Choice模型都与Question模型关联。
用python中简单的类来表示这些概念。编辑polls/models.py文件,使其看起来像下面这样:

#文件 polls/models.py
from django.db import models

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

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

代码十分简单直白。每个模型都被django.db.models.Model的子类来表示。每个模型都有若干个类变量,每个变量都表示模型中的一个数据库字段。
每个字段都由一个Field类的实例表示——比如, CharField表示字符串字段,
DateTimeField表示时间。这将告诉Django每个字段中所存储的数据的类型。
每个 Field实例的名字就是字段的名字,用对机器友好的格式(个人理解就是遵循编码规范)。你将在你的Python代码中使用这个值,并且数据库将使用这个值作为列的名字。
可以在 Field中使用可选的第一个位置参数来指定一个人可读的名称。这是在Django中的几个内省部分使用的,并且它兼具文档(有注释的代码)。如果这个字段没有被提供,Django将使用机器可读的名字。在这个例子中,我们只为Question.pub_date定义了人类可读的名字。对于模型中的其他字段的名字将满足机器可读,同时也满足人类可读。
一些Field类有必须的参数。 CharField,例如,需要你给它一个最大长度(max_length)。这不仅在数据模式中使用,在验证过程中也会用到,我们很快就会看到。
一个字段可以有各种各样的可选参数,既然这样,我们必须设置votes字段的默认值为0。
最后要注意,使用外键(ForeignKey)定义关系。这将告诉Django每个Choice模型都和单个Question模型有关。Django支持所有的常见数据库关系:多对一,多对多,一对一。


激活模型

这一小部分代码给了Django很多信息,随之,Django将会这样做:

  • 为应用程序创建一个数据库模式(CREATE TABLE statements)
  • 创建一套Python访问数据库的API,用于访问Question和Choice对象。
    但是,首先我们应该告诉我们的投票应用程序已经被安装了。
基本原则

Django应用程序是“可插拔的”:你可以在多个项目中使用同一个应用程序,而且你也可以分配应用,因为它们不被Django的安装所束缚。

为了将应用程序包含到我们的项目中,在 INSTALLED_APPS中,我们需要添加一个引用到它的配置类中。PollsConfig类在polls/apps.py文件中,所以它的路径是'polls.apps.PollsConfig'。编辑mysite/settings.py文件,并把刚才的路径添加到 INSTALLED_APPS 的设置中。它看起来是这样的:

#文件 mysite/settings.py
INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

现在Django就知道如何加入投票应用程序了。让我们运行另外一个命令吧:

$ python manage.py makemigrations polls

你应该能从下面看到一些似曾相识的东西:

Migrations for 'polls':
polls/migrations/0001_initial.py:
- Create model Choice
- Create model Question
- Add field question to choice

通过运行makemigrations,你正在告知Django,你已经对模型作出了一些改动(这样的话,你已经创建了新的模型),并且你希望将这些改变作为迁移存储起来。
迁移就是Django如何存储你改变的model(以及你的数据库模式)——它们仅仅是磁盘上的文件。如果你感兴趣的话,可以阅读新的模型的迁移(所谓的迁移,就是一个文件)。就是polls/migrations/0001_initial.py文件。不必担心,你不会在每次Django创建一个之后就阅读它,它被设计为使用者可编辑,以防你想手动编辑Django的改变。
这有一个命令将为你运行迁移,并自动的管理你的数据库模式——这个命令叫做migrate,我们马上就会讲到它。但是在这之前,让我们看看迁移会运行什么SQL。sqlmigrate命令需要迁移应用的名字,然后返回执行的SQL:

$ python manage.py sqlmigrate polls 0001

下面看起来也会似曾相识:(为了便于阅读,我们已经将下文重新格式化)

BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY,
"choice_text" varchar(200) NOT NULL,
"votes" integer NOT NULL
);
--
-- Create model Question

--
CREATE TABLE "polls_question" (
"id" serial NOT NULL PRIMARY KEY,
"question_text" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL
);
--
-- Add field question to choice
--
ALTER TABLE "polls_choice" ADD COLUMN "question_id" integer NOT NULL;
ALTER TABLE "polls_choice" ALTER COLUMN "question_id" DROP DEFAULT;
CREATE INDEX "polls_choice_7aa0f6ee" ON "polls_choice" ("question_id");
ALTER TABLE "polls_choice"
ADD CONSTRAINT "polls_choice_question_id_246c99a640fbbd72_fk_polls_question_id"
FOREIGN KEY ("question_id")
REFERENCES "polls_question" ("id")
DEFERRABLE INITIALLY DEFERRED;
--
COMMIT;

请注意以下几项:

  • 具体的输出将根据所使用的数据库的不同而不同。以上示例使用的是PostgreSQL。
  • 表名是根据应用程序的名字(polls)自动生成的,并将模型Question和Choice都转换为小写字母。(你可以重写这个行为)
  • 主键(IDs)是自动被添加上的。(这个特性你同样可以重写)
  • 外键关系是由外键限制来显示的。不必担心DEFERRABLE这部分;它就是告诉PostgreSQL不要执行外键直到迁移结束。
  • 它是根据你的数据库量身定做的,所以不同数据库的字段例如:auto_increment (MySQL), serial (PostgreSQL), or integer primary key autoincrement (SQLite)是会为你自动处理的。同样适用于引用字段名——例如使用双引号还是单引号。
  • SQL迁移命令实际上并没有在您的数据库上运行迁移——它只是被打印到屏幕上,好让你看到Django认为哪些SQL是需要的。这对查看Django要做什么,或者有数据库管理员要修改脚本是很有用的。
    如果你对此感兴趣,你可以运行python manage.py check;命令,这将检查你项目中的任何问题,而且不需要迁移或者接触数据库。
    现在,再次运行migrate命令,在你的数据库中创建那些表:

$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Rendering model states... DONE
Applying polls.0001_initial... OK

migrate命令会取出所有的未申请的迁移(Django追踪了一个你数据库中名叫“django_migrations”的特殊表格),并且在数据库中运行它们。本质上,将你的更改和数据库模式同步。
迁移很强大,让你随着时间改变模型,当你开发你的项目时,不必删除你的数据库或者数据表直接新建——它专门用于升级数据库,而且不会丢失数据库。在本教程的后面,我们会更深入的介绍它们,但是现在,要记得模型变更的三个指南。

  • 在models.py中修改模型
  • 运行python manage.py makemigrations语句来为这些改变创建迁移。
  • 运行python manage.py migrate,将这些更改应用到数据库。
    产生和应用迁移的单独命令的原因是,你将提交迁移到你的版本控制系统并将它们发送到你的应用程序;它并没有使你的开发变得简单,其他开发人员也可以使用它们。
    阅读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文件。

绕过 manage.py

如果你不愿意使用manage.py,没问题。只需要设置环境变量 DJANGO_SETTINGS_MODULE
为mysite.settings,打开python shell,然后启动Django。

import django
django.setup()

如果这引起了一个 AttributeError,那么你可能使用了和本教程不匹配的Django,你可以选择切换为老教程,也可以更新Django使用跟新的版本。
你必须在 manage.py同一个目录中运行python,或者确定目录在Python的路径上,目的是为了导入mysite。
关于此类更多信息请看 django-admin documentation.

一旦你进入shell,寻找database API

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

No questions are in the system yet.

Question.objects.all()
<QuerySet []>

Create a new Question.

Support for time zones is enabled in the default settings file, so

Django expects a datetime with tzinfo for pub_date. Use timezone.now()

instead of datetime.datetime.now() and it will do the right thing.

from django.utils import timezone
q = Question(question_text="What's new?", pub_date=timezone.now())

Save the object into the database. You have to call save() explicitly.

q.save()

Now it has an ID. Note that this might say "1L" instead of "1", depending

on which database you're using. That's no biggie; it just means your

database backend prefers to return integers as Python long integer

objects.

q.id
1

Access model field values via Python attributes.

q.question_text
"What's new?"
q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

Change values by changing the attributes, then calling save().

q.question_text = "What's up?"
q.save()

objects.all() displays all the questions in the database.

Question.objects.all()
<QuerySet [<Question: Question object>]>

等一会,

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容