Django 官網(wǎng)最新 Tutorial 渣翻 - Part 2

上一節(jié): Django 官網(wǎng)最新 Tutorial 渣翻 - Part 1

手寫(xiě)第一個(gè)Django應(yīng)用, 第二部分

我們本節(jié)開(kāi)始配置數(shù)據(jù)庫(kù),創(chuàng)建你的第一個(gè)model,并且快速了解下Django的自動(dòng)生成的 admin (后臺(tái)管理)頁(yè)面.

數(shù)據(jù)庫(kù)配置

打開(kāi) mysite/settings.py, 這是一個(gè)普通的python模塊, 包含了Django配置的模塊級(jí)變量。
默認(rèn)情況下, Django 用的時(shí) SQLite, 如果你是數(shù)據(jù)庫(kù)新手, 或者僅僅想試一下Django. 這是最簡(jiǎn)單的選擇, python 自帶了SQLite模塊, 所以無(wú)需再裝其他東西, 當(dāng)你真正想寫(xiě)一個(gè)項(xiàng)目時(shí),你可能需要用到功能更豐富的數(shù)據(jù)庫(kù),比如說(shuō)PostgreSQL,避免后面面臨數(shù)據(jù)庫(kù)切換的頭疼問(wèn)題.

如果你想用其他的數(shù)據(jù)庫(kù),請(qǐng)先安裝好相應(yīng)的數(shù)據(jù)庫(kù)軟件 ,并修改settings文件中DATABASES中 'default' 鍵的值,用于連接你的數(shù)據(jù)庫(kù):

  • ENGINE
    可以是’django.db.backends.sqlite3’或者’django.db.backends.postgresql’,’django.db.backends.mysql’, or ’django.db.backends.oracle’,當(dāng)然 其它可用的也行.
  • NAME
    數(shù)據(jù)庫(kù)的名字。如果你使用的是默認(rèn)的SQLite,那么數(shù)據(jù)庫(kù)將作為一個(gè)文件將存放在你的本地機(jī)器內(nèi),NAME應(yīng)該是這個(gè)文件的完整絕對(duì)路徑,包括文件名。設(shè)置中的默認(rèn)值os.path.join(BASE_DIR, ’db.sqlite3’),將把該文件儲(chǔ)存在你的項(xiàng)目目錄下。

如果你不是用SQLite,那你需要配置其他的設(shè)置,如 USER, PASSWORD, and HOST 都是必需的. 詳細(xì)請(qǐng)看 DATABASES相關(guān).

SQLite外的其他數(shù)據(jù)庫(kù):
在使用非SQLite的數(shù)據(jù)庫(kù)時(shí),請(qǐng)務(wù)必首先在數(shù)據(jù)庫(kù)提示符交互模式下創(chuàng)建數(shù)據(jù)庫(kù),你可以使用命令:“CREATE DATABASE database_name;” 確保你在settings文件中提供的數(shù)據(jù)庫(kù)用戶(hù)具有創(chuàng)建數(shù)據(jù)庫(kù)表的權(quán)限,因?yàn)樵诮酉聛?lái)的教程中,我們需要自動(dòng)創(chuàng)建一個(gè)test數(shù)據(jù)庫(kù)。 如果你使用的是SQLite,那么你無(wú)需做任何預(yù)先配置,數(shù)據(jù)庫(kù)文件會(huì)自動(dòng)創(chuàng)建

在修改settings文件時(shí),請(qǐng)順便將TIME_ZONE設(shè)置為你所在的時(shí)區(qū)。(天朝: TIME_ZONE = 'UTC')

同時(shí),請(qǐng)注意settings文件中頂部的INSTALLED_APPS設(shè)置項(xiàng)。它保存了所有的在當(dāng)前項(xiàng)目中被激活的Django應(yīng)用。你必須將你自定義的app注冊(cè)在這里。每個(gè)應(yīng)用可以被多個(gè)項(xiàng)目使用,而且你可以打包和分發(fā)給其他人在他們的項(xiàng)目中使用。

默認(rèn)情況,INSTALLED_APPS 中包含以下應(yīng)用,它們都是Django自帶的:

以上應(yīng)用默認(rèn)會(huì)包含,對(duì)于大多數(shù)項(xiàng)目都是需要的.

上面的每個(gè)應(yīng)用都至少需要使用一個(gè)數(shù)據(jù)庫(kù)表,所以在使用它們之前我們需要在數(shù)據(jù)庫(kù)中創(chuàng)建這些表。使用這個(gè)命令:

python manage.py migrate

migrate命令將根據(jù)INSTALLED_APPS、mysite/settings.py的數(shù)據(jù)庫(kù)設(shè)置以及app的數(shù)據(jù)庫(kù)遷移(稍后會(huì)講到)信息創(chuàng)建相關(guān)的表 ,你將看到每一個(gè)數(shù)據(jù)庫(kù)消息的信息。如果你感興趣,可以在你的數(shù)據(jù)庫(kù)命令行下輸入:\dt (PostgreSQL), SHOW TABLES; (MySQL), 或 .schema (SQLite), 或SELECT TABLE_NAME FROM USER_TABLES; (Oracle) 來(lái)列出 Django 所創(chuàng)建的表。

關(guān)于簡(jiǎn)化
就像我們上面說(shuō)的,默認(rèn)情況下會(huì)自帶那些公共應(yīng)用,但不是每一個(gè)應(yīng)用都需要這么多。如果你不需要其中一個(gè)或所有的,你可以在migrate前,將INSTALLED_APPS內(nèi)注釋掉或者刪除對(duì)應(yīng)的行。 migrate命令只會(huì)針對(duì)INSTALL_APPS進(jìn)行數(shù)據(jù)庫(kù)遷移.


創(chuàng)建Model

現(xiàn)在我們開(kāi)始定義models - 本質(zhì)上,就是你的數(shù)據(jù)庫(kù)結(jié)構(gòu),和其他的一些元數(shù)據(jù)信息.

哲(♂)學(xué)
model就是你唯一明確的真實(shí)數(shù)據(jù)源。Django 遵循 DRY Principle.目的是讓你可以在一個(gè)地方定義你的數(shù)據(jù)模型, 從中生成數(shù)據(jù).

在我們的投票應(yīng)用中,我們將創(chuàng)建兩個(gè)模型:Question and Choice。Question表包含問(wèn)題和發(fā)布日期兩個(gè)字段。Choice表有兩個(gè)字段:選擇文本和投票計(jì)數(shù)。每一條choice都關(guān)聯(lián)到一條Question。

這些概念都由python的類(lèi)來(lái)定義。編輯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)

以上代碼簡(jiǎn)單明了。每一個(gè)model都由一個(gè)類(lèi)來(lái)定義,該類(lèi)是django.db.models.Model的子類(lèi)。每個(gè)類(lèi)都由數(shù)個(gè)變量組成,分別對(duì)應(yīng)了數(shù)據(jù)庫(kù)里的字段。

每一個(gè)字段都是Field 類(lèi)的實(shí)例 -- 如 CharField是字符串字段,DateTimeField是時(shí)間字段。這告訴Django每個(gè)字段用來(lái)存儲(chǔ)什么類(lèi)型的數(shù)據(jù)。

每個(gè)Field的實(shí)例名(如question_text 或 pub_date)就是字段的名字名,一個(gè)機(jī)器友好型的名字。在代碼里你會(huì)用到它,而數(shù)據(jù)庫(kù)里用它來(lái)作字段名。

每個(gè)Filed里的第一個(gè)可選的位置參數(shù),常常被用來(lái)指定一個(gè)可讀性好的名字。這在Django的一些內(nèi)部機(jī)制中有所用處,也可以兼做文檔。如果沒(méi)有指定這個(gè)字段,Django會(huì)默認(rèn)使用機(jī)器可讀的名字。在這個(gè)例子中,我們只為pub_data定義了友好的名字。model的其他字段已經(jīng)通俗易懂。

有一些字段有必選參數(shù)。例如,CharField要求你給它一個(gè)max_length。這個(gè)參數(shù)不僅在建表時(shí)用到,在數(shù)據(jù)驗(yàn)證中也會(huì)用到,我們稍后會(huì)看到。

Field 還具有各種可選位置參數(shù)。在這個(gè)例子中,我們?cè)O(shè)置votes字段的default參數(shù)為0。

最后,注意我們使用ForeignKey定義了一個(gè)外鍵關(guān)聯(lián)。它告訴Django每個(gè)Choice都只關(guān)聯(lián)一個(gè)Question。Django支持所有常見(jiàn)的數(shù)據(jù)庫(kù)關(guān)聯(lián):多對(duì)一、多對(duì)多和一對(duì)一。


激活 model

這簡(jiǎn)短的model代碼給了Django許多信息。有了它,Django就可以:

  • 為該應(yīng)用創(chuàng)建數(shù)據(jù)庫(kù)表(CREATE TABLE 語(yǔ)句)。
  • 創(chuàng)建一個(gè)訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的 python API 來(lái)訪(fǎng)問(wèn)Question對(duì)象和Choice對(duì)象。

但是,我們首先得告訴項(xiàng)目:polls應(yīng)用已經(jīng)安裝。

哲學(xué)
Django 應(yīng)用是“插件化”的,即可以在多個(gè)項(xiàng)目中使用同一個(gè)應(yīng)用,也可以分發(fā)這些應(yīng)用, 因?yàn)樗鼈儾恍枰c某個(gè)特定的Django安裝綁定。

為了將App整合進(jìn)項(xiàng)目里,我們需要在 settings.py 的 INSTALLED_APPS 里添加該 App 的引用,PollsConfig 類(lèi)在 polls/apps.py 文件中,所以按照點(diǎn)來(lái)分割路徑就是polls.apps.PollsConfig,編輯mysite/settings.py文件,在 INSTALLED_APPS中添加按點(diǎn)分割的路徑,如下:

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',
]

現(xiàn)在Django就知道他整合了polls應(yīng)用。我們輸入以下命令:

python manage.py makemigrations polls

你可以看到類(lèi)似以下的輸出:

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

通過(guò)運(yùn)行makemigrations,你將告訴Django你已經(jīng)對(duì)你的models做了一些修改(在本例中,你創(chuàng)建了新的model類(lèi)),這些修改會(huì)作為migration記錄來(lái)存儲(chǔ)。

Migrations 就是Django存儲(chǔ)的models修改記錄(也就是數(shù)據(jù)庫(kù)表) - 他們只是在磁盤(pán)的文件, 你可以查看剛剛創(chuàng)建新model時(shí)產(chǎn)生的migration, 他們?cè)?code>polls/migrations/0001_initial.py文件里, 別擔(dān)心, 你無(wú)需每次都去看一下, 但是他們是可編輯的, 以便有時(shí)候你想修改他們.

There’s a command that will run the migrations for you and manage your database schema automatically - that’s called migrate, and we’ll come to it in a moment - but first, let’s see what SQL that migration would run. The sqlmigrate command takes migration names and returns their SQL:

有一個(gè)命令可以運(yùn)行這些migrations文件來(lái)自動(dòng)管理你的數(shù)據(jù)庫(kù)表, -- 它就是migrate, 我們待會(huì)兒會(huì)用到它 -- 但首先我們看一下,那些migration會(huì)執(zhí)行哪些sql語(yǔ)句。sqlmigrate 命令接收migration文件名,并返回sql語(yǔ)句:

 python manage.py sqlmigrate polls 0001

你將看到類(lèi)似以下輸出(我們重新排版了下)

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;

請(qǐng)注意以下幾點(diǎn):

  • 輸出的具體內(nèi)容會(huì)依據(jù)你使用的數(shù)據(jù)庫(kù)而不同。 以上例子使用的數(shù)據(jù)庫(kù)是PostgreSQL。
  • 表名是自動(dòng)生成的,由app的名字(polls)和模型名字的小寫(xiě)字母組合而成 —— question和choice。(你可以重寫(xiě)這個(gè)行為。)
  • 主鍵(IDs)是自動(dòng)添加的。 (你也可以重寫(xiě)這個(gè)行為。)
  • 按照慣例,Django會(huì)在外鍵的字段名后面添加 "_id"。(是的,你依然可以重寫(xiě)這個(gè)行為。)
  • 外鍵關(guān)系由FOREIGN KEY約束顯式聲明。不用在意DEFERRABLE 部分;它只是告訴PostgreSQL直到事務(wù)的最后再執(zhí)行外鍵關(guān)聯(lián)。
  • 這些SQL語(yǔ)句是針對(duì)你所使用的數(shù)據(jù)庫(kù)定制的,所以會(huì)為你自動(dòng)處理某些數(shù)據(jù)庫(kù)所特有的字段例如auto_increment(MySQL)、 serial (PostgreSQL)或integer primary key autoincrement (SQLite) 。在處理字段名的引號(hào)時(shí)也是如此 —— 例如,使用雙引號(hào)還是單引號(hào)。
  • sqlmigrate 命令并不會(huì)在你的數(shù)據(jù)庫(kù)上真正運(yùn)行遷移文件 —— 它只是把Django 認(rèn)為需要的SQL打印在屏幕上以讓你能夠看到。 這對(duì)于檢查Django將要進(jìn)行的數(shù)據(jù)庫(kù)操作或者你的數(shù)據(jù)庫(kù)管理員需要這些SQL腳本是非常有用的。

如果有興趣,你還可以運(yùn)行python manage.py check, 它會(huì)檢查你的項(xiàng)目中的模型是否存在問(wèn)題,而不用執(zhí)行遷移或者操作數(shù)據(jù)庫(kù)

現(xiàn)在,再次運(yùn)行 migrate, 在你的數(shù)據(jù)庫(kù)中創(chuàng)建model所對(duì)應(yīng)的表:

$ 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 命令將找到所有尚未被應(yīng)用的遷移文件(Django有專(zhuān)門(mén)的一張表 - django_migrations, 來(lái)追蹤哪些遷移文件已經(jīng)被應(yīng)用過(guò)),并且在你的數(shù)據(jù)庫(kù)上運(yùn)行它們 —— 本質(zhì)上來(lái)講,就是同步你對(duì)models的修改到數(shù)據(jù)庫(kù)表中。)

Migrations 功能非常強(qiáng)大,在你開(kāi)發(fā)項(xiàng)目的過(guò)程中,當(dāng)你在更改models后,無(wú)需刪除數(shù)據(jù)庫(kù)或表再重建。它專(zhuān)注于熱升級(jí)你的數(shù)據(jù)庫(kù)且不丟數(shù)據(jù)。我們將在本教程的后續(xù)章節(jié)中詳細(xì)介紹,但是現(xiàn)在,請(qǐng)記住模型變更的三個(gè)基本步驟:

將生成和應(yīng)用Migrations命令分開(kāi), 是因?yàn)槟憧赡苄枰獙⑦w移文件提交到你的版本控制器并跟隨你的應(yīng)用, 這樣做不僅使開(kāi)發(fā)變得更加簡(jiǎn)單,而且對(duì)其他開(kāi)發(fā)者以及線(xiàn)上環(huán)境非常有用。

閱讀 django-admin documentation 來(lái)詳細(xì)了解manage.py 工具所能做的事情。

玩玩API

現(xiàn)在,我們切換到python shell的交互模式,感受一下Django給的API。用如下命令來(lái)調(diào)出python shell:

$ python manage.py shell

我們使用這個(gè)(python manage.py shell)而不是直接進(jìn)入python交互環(huán)境(python), 因?yàn)?code>manage.py設(shè)置了DJANGO_SETTINGS_MODULE環(huán)境變量. 它告訴Django導(dǎo)入了mysite/settings.py模塊.

一旦你進(jìn)入了這個(gè)python shell, 那我們就開(kāi)始探索這些database API吧:

>>> from polls.models import Choice, Question  # 導(dǎo)入我們剛剛創(chuàng)建的model類(lèi).

# 目前還沒(méi)有questions對(duì)象
>>> Question.objects.all()
<QuerySet []>

# 創(chuàng)建一個(gè)Questions對(duì)象
# 默認(rèn)的設(shè)置文件中是支持時(shí)區(qū)的, 
# 所以Django會(huì)通過(guò) tzinfo 模塊給 pub_date 一個(gè)datetime.
# 使用timezone.now(), 它會(huì)替代datetime.datetime.now()完成時(shí)間設(shè)置工作.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

# 調(diào)用 save() 來(lái)將對(duì)象保存進(jìn)數(shù)據(jù)庫(kù)
>>> q.save()

# 現(xiàn)在他有一個(gè)id了
>>> q.id
1

# 通過(guò)訪(fǎng)問(wèn)Python屬性的方式來(lái)訪(fǎng)問(wèn)model字段的值
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# 通過(guò)改變對(duì)象屬性的方式來(lái)改變字段的值, 改變后需要調(diào)用save()才能生效
>>> q.question_text = "What's up?"
>>> q.save()

# objects.all() 顯示所有在數(shù)據(jù)庫(kù)中的questions對(duì)象
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>

秋德馬嘚, <Question: Question object (1)>是什么鬼? 這可不是一種友好的對(duì)象表示方式, 讓我們編輯Question 模型(在 polls/models.py 文件中)來(lái)完善他, 對(duì)Question and Choice類(lèi)都添加__str__() 方法:

polls/models.py

from django.db import models

class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text

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

給你的模型類(lèi)添加__str__() 方法很重要,不僅會(huì)使你自己在使用交互式命令行時(shí)看得更加方便,而且會(huì)在Django自動(dòng)生成的管理界面中對(duì)模型對(duì)象使用這種表示。

這是非常普通的Python方法?,F(xiàn)在讓我們來(lái)演示一下如何添加自定義方法:

polls/models.py

import datetime

from django.db import models
from django.utils import timezone


class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

注意import datetimefrom django.utils import timezone分別引用Python 的標(biāo)準(zhǔn)datetime 模塊和 Django的django.utils.timezone中時(shí)區(qū)相關(guān)的工具, 如果你不了解Python中時(shí)區(qū)的處理方法,你可以在time zone support docs中了解更多的知識(shí)。

保存這些改動(dòng),然后通過(guò)python manage.py shell另外打開(kāi)一個(gè)新的Python 交互式shell:

>>> from polls.models import Choice, Question

# 確保我們添加的__str__方法生效了
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django提供大量的數(shù)據(jù)庫(kù)查詢(xún)API, 通過(guò)關(guān)鍵字參數(shù)的方式來(lái)調(diào)用.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# 得到今年發(fā)布的question對(duì)象
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# 當(dāng)請(qǐng)求的ID不存在時(shí), 會(huì)拋出異常
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# 大多數(shù)情況下都是通過(guò)主鍵進(jìn)行查詢(xún), 所以Django提供一個(gè)關(guān)于主鍵查詢(xún)的快捷方式
# 以下與Question.objects.get(id=1)是一樣的.
>>> Question.objects.get(pk=1)
<Question: What's up?>

# 確保我們自定義方法生效
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# 每個(gè)question對(duì)象都有多個(gè)choice對(duì)象(一對(duì)多), 調(diào)用 create 來(lái)構(gòu)造一個(gè)新的 choice 對(duì)象,
# 它會(huì)使用 INSERT 語(yǔ)句, 添加choice對(duì)象的一系列字段, 然后返回一個(gè)choice對(duì)象, 
# django通過(guò)API來(lái)創(chuàng)建一個(gè)含有"反向關(guān)聯(lián)"關(guān)系的外鍵集合.首先, 我們要獲取指定的question對(duì)象
>>> q = Question.objects.get(pk=1)

# 顯示所有與choices對(duì)象有關(guān)系的對(duì)象集合 -- 目前沒(méi)有
>>> q.choice_set.all()
<QuerySet []>

# 創(chuàng)建3個(gè)choice對(duì)象
# (譯者注: choice類(lèi)中定義了question的外鍵, 所以question可以通過(guò)`類(lèi)名_set`來(lái)反向關(guān)聯(lián), 
# 也可以通過(guò)定義外鍵時(shí)設(shè)置的related_name參數(shù)的值來(lái)進(jìn)行反向關(guān)聯(lián))
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)

# Choice 對(duì)象有API來(lái)訪(fǎng)問(wèn)他們關(guān)聯(lián)的 Question 對(duì)象
>>> c.question
<Question: What's up?>

# 反之亦然: Question對(duì)象也可以訪(fǎng)問(wèn)Choice對(duì)象.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3

# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# 我們可以使用雙下劃線(xiàn)來(lái)調(diào)用API自動(dòng)的處理關(guān)系, 其中關(guān)系的深度沒(méi)有限制.(這段感覺(jué)沒(méi)翻譯好, 原文在)
# 如下, 找到所有 pub_date 為今年, 并且可以是屬于任何Question的Choice(這里重用了我們?cè)谏厦鎰?chuàng)建的`current_year`變量.
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# 我們可以使用delete()來(lái)刪除這些choices QuerySet中的一個(gè).
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

更多關(guān)于模型相關(guān)的信息,請(qǐng)查看 Accessing related objects。更多關(guān)于如何在這些API中使用雙下劃線(xiàn)來(lái)執(zhí)行字段查詢(xún)的信息,請(qǐng)查看 Field lookups.。想了解所有數(shù)據(jù)庫(kù)API的信息,請(qǐng)查看我們的 Database API reference.


介紹 Django Admin

哲♂學(xué)
為你的團(tuán)隊(duì)或客戶(hù)編寫(xiě)增刪改查的admin管理系統(tǒng)是非常乏味的,也沒(méi)有多少創(chuàng)造性?xún)r(jià)值?;谶@考慮,Django自動(dòng)的為你的models創(chuàng)建了管理接口。
Django最初是為新聞?wù)军c(diǎn)開(kāi)發(fā)的,新聞發(fā)布者和公共站點(diǎn)界限明顯。管理員通過(guò)這個(gè)系統(tǒng)添加新聞、時(shí)間、體育賽事等,這些信息展示在公共網(wǎng)站上。Django提供了一個(gè)統(tǒng)一接口給站點(diǎn)管理員來(lái)編輯內(nèi)容。
admin系統(tǒng)并不是為了訪(fǎng)客設(shè)計(jì)的,只對(duì)站點(diǎn)管理員開(kāi)放。

創(chuàng)建管理員

首先我們需要?jiǎng)?chuàng)建一個(gè)能登錄admin站點(diǎn)的用戶(hù),運(yùn)行以下命令:

python manage.py createsuperuser

輸入你喜歡的名字,按下回車(chē):

Username: admin

然后會(huì)提示輸入你的郵箱:

Email address: admin@example.com

最后一步是輸入密碼。你需要輸入兩次,第二次作為第一次的進(jìn)一步確認(rèn):

Password: **********
Password (again): *********
Superuser created successfully.

啟動(dòng)開(kāi)發(fā)服務(wù)器

Django的admin站點(diǎn)默認(rèn)是激活的。讓我們開(kāi)啟開(kāi)發(fā)服務(wù)器來(lái)探索一下:

如果服務(wù)器沒(méi)開(kāi)啟,用下面的方法來(lái)啟動(dòng):

python manage.py runserver

現(xiàn)在,打開(kāi)web瀏覽器,本地域名訪(fǎng)問(wèn)“/admin/” -- 比如說(shuō)http://127.0.0.1:8000/admin/。你可以看到admin的登錄界面:

translation 默認(rèn)是開(kāi)啟的,登錄界面顯示的應(yīng)該是你的母語(yǔ),這取決于你的瀏覽器設(shè)置,如果Django有這種翻譯版本的話(huà)。


進(jìn)入admin頁(yè)面

現(xiàn)在,你可以用你剛剛創(chuàng)建的超級(jí)用戶(hù)來(lái)登錄了。登錄后你應(yīng)該可以看到如下index頁(yè)面:


當(dāng)前已經(jīng)有兩個(gè)可編輯的內(nèi)容:groups和users。它們是 django.contrib.auth模塊提供的身份認(rèn)證框架。

在admin中注冊(cè)投票應(yīng)用

但是我們創(chuàng)建的投票應(yīng)用哪去了呢?它并沒(méi)有在admin的首頁(yè)里。我們還有一件事要做:告訴admin站點(diǎn)Question要有admin交互界面。編輯polls/admin.py文件,代碼如下:

polls/admin.py

from django.contrib import admin

from .models import Question

admin.site.register(Question)

探索Admin功能

Question注冊(cè)之后,Django就知道要將它展示在admin的首頁(yè)了。



點(diǎn)擊“Questions”。 現(xiàn)在,你會(huì)進(jìn)入Question的“變更列表”。 這個(gè)界面顯示了數(shù)據(jù)庫(kù)中的所有question,你可以選擇一個(gè)來(lái)更改它。 我們?cè)谇懊鎰?chuàng)建的“What’s up?” Question對(duì)象也在這里:



點(diǎn)擊“What’s up?” Question對(duì)象來(lái)編輯它:

注意事項(xiàng):

  • 這個(gè)表單是根據(jù)Question 模型文件自動(dòng)生成的。
  • 模型中不同類(lèi)型的字段(DateTimeField, CharField)會(huì)對(duì)應(yīng)相應(yīng)的HTML輸入控件。每一種類(lèi)型的字段,Django管理站點(diǎn)都知道如何顯示它們。
  • 每個(gè)DateTimeField 字段都會(huì)有個(gè)方便的JavaScript快捷鍵。Date有個(gè)“Today”的快捷鍵和一個(gè)彈出式日歷,time欄有個(gè)“Now”的快捷鍵和一個(gè)列出常用時(shí)間選項(xiàng)的彈出式窗口。

界面的底部提供了幾個(gè)按鈕:

  • Save —— 保存更改,并返回當(dāng)前類(lèi)型對(duì)象的變更列表界面。
  • Save and continue editing —— 保存更改并且重新載入當(dāng)前對(duì)象的管理界面。
  • Save and add another —— 保存更改并且載入一個(gè)當(dāng)前類(lèi)型對(duì)象的新的、空白的表單。
  • Delete —— 顯示一個(gè)刪除確認(rèn)界面。

如果“Date published”的值和你在教程1中創(chuàng)建這個(gè)Question對(duì)象時(shí)的時(shí)間不相符,可能是因?yàn)槟阃泴IME_ZONE設(shè)置為你當(dāng)?shù)氐臅r(shí)區(qū)。修改它,然后刷新界面,再次檢查一下是否正確。

通過(guò)“Today”和“Now”這兩個(gè)快捷鍵更改“Date published”字段。,然后點(diǎn)擊 “Save and continue editing”。然后點(diǎn)擊右上角的“History”按鈕。 你將看到一個(gè)頁(yè)面,列出了通過(guò)Django管理界面對(duì)此對(duì)象所做的全部更改的清單,包含有時(shí)間戳和修改人的姓名等信息:

當(dāng)你適應(yīng)了models的API,熟悉了admin站點(diǎn)后,請(qǐng)移步 part 3 of this tutorial 來(lái)學(xué)習(xí)如何給投票應(yīng)用編寫(xiě)更多的views函數(shù).

下一節(jié): Django 官網(wǎng)最新 Tutorial 渣翻 - Part 3

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容