Django4.0 開始-編寫你的第一個(gè)Django應(yīng)用,第2部分

2022-03-29 16:12 更新

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

現(xiàn)在,打開 ?mysite/settings.py? 。這是個(gè)包含了 Django 項(xiàng)目設(shè)置的 Python 模塊。
通常,這個(gè)配置文件使用 SQLite 作為默認(rèn)數(shù)據(jù)庫。如果你不熟悉數(shù)據(jù)庫,或者只是想嘗試下 Django,這是最簡單的選擇。Python 內(nèi)置 SQLite,所以你無需安裝額外東西來使用它。當(dāng)你開始一個(gè)真正的項(xiàng)目時(shí),你可能更傾向使用一個(gè)更具擴(kuò)展性的數(shù)據(jù)庫,例如 PostgreSQL,避免中途切換數(shù)據(jù)庫這個(gè)令人頭疼的問題。
如果你想使用其他數(shù)據(jù)庫,你需要安裝合適的 ?database bindings? ,然后改變?cè)O(shè)置文件中 ?DATABASES 'default'? 項(xiàng)目中的一些鍵值:

  • ?ENGINE ?-- 可選值有 ?'django.db.backends.sqlite3'?,?'django.db.backends.postgresql'?,?'django.db.backends.mysql'?,或 ?'django.db.backends.oracle'?。
  • ?NAME ?-- 數(shù)據(jù)庫的名稱。如果你使用 SQLite,數(shù)據(jù)庫將是你電腦上的一個(gè)文件,在這種情況下,?NAME應(yīng)該是此文件完整的絕對(duì)路徑,包括文件名。默認(rèn)值 ?BASE_DIR / 'db.sqlite3'? 將把數(shù)據(jù)庫文件儲(chǔ)存在項(xiàng)目的根目錄。

如果你不使用 SQLite,則必須添加一些額外設(shè)置,比如 ?USER ?、 ?PASSWORD ?、 ?HOST ?等等。

編輯 ?mysite/settings.py? 文件前,先設(shè)置 ?TIME_ZONE為你自己時(shí)區(qū)。

此外,關(guān)注一下文件頭部的 ?INSTALLED_APPS設(shè)置項(xiàng)。這里包括了會(huì)在你項(xiàng)目中啟用的所有 Django 應(yīng)用。應(yīng)用能在多個(gè)項(xiàng)目中使用,你也可以打包并且發(fā)布應(yīng)用,讓別人使用它們。
通常, ?INSTALLED_APPS默認(rèn)包括了以下 Django 的自帶應(yīng)用:

  • ?django.contrib.admin? -- 管理員站點(diǎn), 你很快就會(huì)使用它。
  • ?django.contrib.auth? -- 認(rèn)證授權(quán)系統(tǒng)。
  • ?django.contrib.contenttypes? -- 內(nèi)容類型框架。
  • ?django.contrib.sessions? -- 會(huì)話框架。
  • ?django.contrib.messages? -- 消息框架。
  • ?django.contrib.staticfiles? -- 管理靜態(tài)文件的框架。

這些應(yīng)用被默認(rèn)啟用是為了給常規(guī)項(xiàng)目提供方便。

默認(rèn)開啟的某些應(yīng)用需要至少一個(gè)數(shù)據(jù)表,所以,在使用他們之前需要在數(shù)據(jù)庫中創(chuàng)建一些表。請(qǐng)執(zhí)行以下命令:

...\> py manage.py migrate

這個(gè) ?migrate命令查看 ?INSTALLED_APPS ?配置,并根據(jù) ?mysite/settings.py? 文件中的數(shù)據(jù)庫配置和隨應(yīng)用提供的數(shù)據(jù)庫遷移文件(我們將在后面介紹這些),創(chuàng)建任何必要的數(shù)據(jù)庫表。你會(huì)看到它應(yīng)用的每一個(gè)遷移都有一個(gè)消息。如果你有興趣,運(yùn)行你的數(shù)據(jù)庫的命令行客戶端,輸入? \dt? (PostgreSQL), ?SHOW TABLES;? (MariaDB,MySQL),? .tables? (SQLite)或 ?SELECT TABLE_NAME FROM USER_TABLES;? (Oracle)來顯示 Django 創(chuàng)建的表。

創(chuàng)建模型

在 Django 里寫一個(gè)數(shù)據(jù)庫驅(qū)動(dòng)的 Web 應(yīng)用的第一步是定義模型 - 也就是數(shù)據(jù)庫結(jié)構(gòu)設(shè)計(jì)和附加的其它元數(shù)據(jù)。

在這個(gè)投票應(yīng)用中,需要?jiǎng)?chuàng)建兩個(gè)模型:問題 ?Question ?和選項(xiàng) ?Choice?。?Question ?模型包括問題描述和發(fā)布時(shí)間。?Choice ?模型有兩個(gè)字段,選項(xiàng)描述和當(dāng)前得票數(shù)。每個(gè)選項(xiàng)屬于一個(gè)問題。
這些概念可以通過一個(gè) Python 類來描述。按照下面的例子來編輯 ?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)

每個(gè)模型被表示為 ?django.db.models.Model? 類的子類。每個(gè)模型有許多類變量,它們都表示模型里的一個(gè)數(shù)據(jù)庫字段。
每個(gè)字段都是 ?Field類的實(shí)例 - 比如,字符字段被表示為 ?CharField,日期時(shí)間字段被表示為 ?DateTimeField。這將告訴 Django 每個(gè)字段要處理的數(shù)據(jù)類型。

每個(gè) Field 類實(shí)例變量的名字(例如 ?question_text ?或 ?pub_date ?)也是字段名,所以最好使用對(duì)機(jī)器友好的格式。你將會(huì)在 Python 代碼里使用它們,而數(shù)據(jù)庫會(huì)將它們作為列名。
你可以使用可選的選項(xiàng)來為 Field 定義一個(gè)人類可讀的名字。這個(gè)功能在很多 Django 內(nèi)部組成部分中都被使用了,而且作為文檔的一部分。如果某個(gè)字段沒有提供此名稱,Django 將會(huì)使用對(duì)機(jī)器友好的名稱,也就是變量名。在上面的例子中,我們只為 ?Question.pub_date? 定義了對(duì)人類友好的名字。對(duì)于模型內(nèi)的其它字段,它們的機(jī)器友好名也會(huì)被作為人類友好名使用。

定義某些 ?Field ?類實(shí)例需要參數(shù)。例如 ?CharField ?需要一個(gè) ?max_length ?參數(shù)。這個(gè)參數(shù)的用處不止于用來定義數(shù)據(jù)庫結(jié)構(gòu),也用于驗(yàn)證數(shù)據(jù),我們稍后將會(huì)看到這方面的內(nèi)容。
?Field ?也能夠接收多個(gè)可選參數(shù);在上面的例子中:我們將 ?votes ?的 ?default ?也就是默認(rèn)值,設(shè)為0。
注意在最后,我們使用 ?ForeignKey ?定義了一個(gè)關(guān)系。這將告訴 Django,每個(gè) ?Choice ?對(duì)象都關(guān)聯(lián)到一個(gè) ?Question ?對(duì)象。Django 支持所有常用的數(shù)據(jù)庫關(guān)系:多對(duì)一、多對(duì)多和一對(duì)一。

激活模型

上面的一小段用于創(chuàng)建模型的代碼給了 Django 很多信息,通過這些信息,Django 可以:

  • 為這個(gè)應(yīng)用創(chuàng)建數(shù)據(jù)庫 ?schema?(生成 ?CREATE TABLE? 語句)。
  • 創(chuàng)建可以與 ?Question ?和 ?Choice ?對(duì)象進(jìn)行交互的 Python 數(shù)據(jù)庫 API。

但是首先得把 ?polls ?應(yīng)用安裝到我們的項(xiàng)目里。

為了在我們的工程中包含這個(gè)應(yīng)用,我們需要在配置類 ?INSTALLED_APPS ?中添加設(shè)置。因?yàn)??PollsConfig ?類寫在文件 ?polls/apps.py? 中,所以它的點(diǎn)式路徑是 ?'polls.apps.PollsConfig'?。在文件 ?mysite/settings.py? 中 ?INSTALLED_APPS ?子項(xiàng)添加點(diǎn)式路徑后,它看起來像這樣:

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 項(xiàng)目會(huì)包含 polls 應(yīng)用。接著運(yùn)行下面的命令:

...\> py manage.py makemigrations polls

你將會(huì)看到類似于下面這樣的輸出:

Migrations for 'polls':
  polls/migrations/0001_initial.py
    - Create model Question
    - Create model Choice

通過運(yùn)行 ?makemigrations ?命令,Django 會(huì)檢測你對(duì)模型文件的修改(在這種情況下,你已經(jīng)取得了新的),并且把修改的部分儲(chǔ)存為一次 遷移。
遷移是 Django 對(duì)于模型定義(也就是你的數(shù)據(jù)庫結(jié)構(gòu))的變化的儲(chǔ)存形式 - 它們其實(shí)也只是一些你磁盤上的文件。如果你想的話,你可以閱讀一下你模型的遷移數(shù)據(jù),它被儲(chǔ)存在 ?polls/migrations/0001_initial.py? 里。別擔(dān)心,你不需要每次都閱讀遷移文件,但是它們被設(shè)計(jì)成人類可讀的形式,這是為了便于你手動(dòng)調(diào)整 Django 的修改方式。
Django 有一個(gè)自動(dòng)執(zhí)行數(shù)據(jù)庫遷移并同步管理你的數(shù)據(jù)庫結(jié)構(gòu)的命令 - 這個(gè)命令是 ?migrate?,我們馬上就會(huì)接觸它 - 但是首先,讓我們看看遷移命令會(huì)執(zhí)行哪些 SQL 語句。?sqlmigrate ?命令接收一個(gè)遷移的名稱,然后返回對(duì)應(yīng)的 SQL:

...\> py manage.py sqlmigrate polls 0001

你將會(huì)看到類似下面這樣的輸出(我把輸出重組成了人類可讀的格式):

BEGIN;
--
-- 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
);
--
-- Create model Choice
--
CREATE TABLE "polls_choice" (
    "id" serial NOT NULL PRIMARY KEY,
    "choice_text" varchar(200) NOT NULL,
    "votes" integer NOT NULL,
    "question_id" integer NOT NULL
);
ALTER TABLE "polls_choice"
  ADD CONSTRAINT "polls_choice_question_id_c5b4b260_fk_polls_question_id"
    FOREIGN KEY ("question_id")
    REFERENCES "polls_question" ("id")
    DEFERRABLE INITIALLY DEFERRED;
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");

COMMIT;

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

  • 輸出的內(nèi)容和你使用的數(shù)據(jù)庫有關(guān),上面的輸出示例使用的是 PostgreSQL。
  • 數(shù)據(jù)庫的表名是由應(yīng)用名(?polls?)和模型名的小寫形式( ?question ?和 ?choice?)連接而來。(如果需要,你可以自定義此行為。)主鍵(IDs)會(huì)被自動(dòng)創(chuàng)建。(當(dāng)然,你也可以自定義。)
  • 默認(rèn)的,Django 會(huì)在外鍵字段名后追加字符串 ?"_id"? 。(同樣,這也可以自定義。)
  • 外鍵關(guān)系由 ?FOREIGN KEY? 生成。你不用關(guān)心 ?DEFERRABLE部分,它只是告訴 PostgreSQL,請(qǐng)?jiān)谑聞?wù)全都執(zhí)行完之后再創(chuàng)建外鍵關(guān)系。
  • 生成的 SQL 語句是為你所用的數(shù)據(jù)庫定制的,所以那些和數(shù)據(jù)庫有關(guān)的字段類型,比如 ?auto_increment(MySQL)、 ?serial ?(PostgreSQL)和 ?integer primary key ?autoincrement? ?(SQLite),Django 會(huì)幫你自動(dòng)處理。那些和引號(hào)相關(guān)的事情 - 例如,是使用單引號(hào)還是雙引號(hào) - 也一樣會(huì)被自動(dòng)處理。
  • 這個(gè) ?sqlmigrate命令并沒有真正在你的數(shù)據(jù)庫中的執(zhí)行遷移 - 相反,它只是把命令輸出到屏幕上,讓你看看 Django 認(rèn)為需要執(zhí)行哪些 SQL 語句。這在你想看看 Django 到底準(zhǔn)備做什么,或者當(dāng)你是數(shù)據(jù)庫管理員,需要寫腳本來批量處理數(shù)據(jù)庫時(shí)會(huì)很有用。

如果你感興趣,你也可以試試運(yùn)行 ?python manage.py check ;?這個(gè)命令幫助你檢查項(xiàng)目中的問題,并且在檢查過程中不會(huì)對(duì)數(shù)據(jù)庫進(jìn)行任何操作。
現(xiàn)在,再次運(yùn)行 ?migrate命令,在數(shù)據(jù)庫里創(chuàng)建新定義的模型的數(shù)據(jù)表:

...\> py 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

這個(gè) ?migrate命令選中所有還沒有執(zhí)行過的遷移(Django 通過在數(shù)據(jù)庫中創(chuàng)建一個(gè)特殊的表 ?django_migrations來跟蹤執(zhí)行過哪些遷移)并應(yīng)用在數(shù)據(jù)庫上 - 也就是將你對(duì)模型的更改同步到數(shù)據(jù)庫結(jié)構(gòu)上。
遷移是非常強(qiáng)大的功能,它能讓你在開發(fā)過程中持續(xù)的改變數(shù)據(jù)庫結(jié)構(gòu)而不需要重新刪除和創(chuàng)建表 - 它專注于使數(shù)據(jù)庫平滑升級(jí)而不會(huì)丟失數(shù)據(jù)。我們會(huì)在后面的教程中更加深入的學(xué)習(xí)這部分內(nèi)容,現(xiàn)在,你只需要記住,改變模型需要這三步:

  • 編輯 ?models.py? 文件,改變模型。
  • 運(yùn)行 ?python manage.py makemigrations? 為模型的改變生成遷移文件。
  • 運(yùn)行 ?python manage.py migrate? 來應(yīng)用數(shù)據(jù)庫遷移。

數(shù)據(jù)庫遷移被分解成生成和應(yīng)用兩個(gè)命令是為了讓你能夠在代碼控制系統(tǒng)上提交遷移數(shù)據(jù)并使其能在多個(gè)應(yīng)用里使用;這不僅僅會(huì)讓開發(fā)更加簡單,也給別的開發(fā)者和生產(chǎn)環(huán)境中的使用帶來方便。

初試API

現(xiàn)在讓我們進(jìn)入交互式 Python 命令行,嘗試一下 Django 為你創(chuàng)建的各種 API。通過以下命令打開 Python 命令行:

...\> py manage.py shell

我們使用這個(gè)命令而不是簡單的使用“python”是因?yàn)??manage.py? 會(huì)設(shè)置 ?DJANGO_SETTINGS_MODULE環(huán)境變量,這個(gè)變量會(huì)讓 Django 根據(jù) ?mysite/settings.py? 文件來設(shè)置 Python 包的導(dǎo)入路徑。
當(dāng)你成功進(jìn)入命令行后,來試試 數(shù)據(jù)庫 API 吧:

>>> from polls.models import Choice, Question  # 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.
>>> 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 (1)>]>

?<Question: Question object (1)>? 對(duì)于我們了解這個(gè)對(duì)象的細(xì)節(jié)沒什么幫助。讓我們通過編輯 ?Question ?模型的代碼(位于 ?polls/models.py? 中)來修復(fù)這個(gè)問題。給 ?Question和 ?Choice增加 ?__str__()? 方法。

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

給模型增加 ?__str__()? 方法是很重要的,這不僅僅能給你在命令行里使用帶來方便,Django 自動(dòng)生成的 admin 里也使用這個(gè)方法來表示對(duì)象。
讓我們?cè)贋榇四P吞砑右粋€(gè)自定義方法:

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 datetime? 和 ?from django.utils import timezone? 分別導(dǎo)入了 Python 的標(biāo)準(zhǔn) ?datetime模塊和 Django 中和時(shí)區(qū)相關(guān)的 ?django.utils.timezone? 工具模塊。
保存文件然后通過 ?python manage.py shell命令再次打開 Python 交互式命令行:

>>> from polls.models import Choice, Question

# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>

# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)

# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>

# Create three choices.
>>> 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 objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>

# And vice versa: Question objects get access to Choice objects.
>>> 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.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

介紹Django管理頁面

為你的員工或客戶生成一個(gè)用戶添加,修改和刪除內(nèi)容的后臺(tái)是一項(xiàng)缺乏創(chuàng)造性和乏味的工作。因此,Django 全自動(dòng)地根據(jù)模型創(chuàng)建后臺(tái)界面。
Django 產(chǎn)生于一個(gè)公眾頁面和內(nèi)容發(fā)布者頁面完全分離的新聞?lì)愓军c(diǎn)的開發(fā)過程中。站點(diǎn)管理人員使用管理系統(tǒng)來添加新聞、事件和體育時(shí)訊等,這些添加的內(nèi)容被顯示在公眾頁面上。Django 通過為站點(diǎn)管理人員創(chuàng)建統(tǒng)一的內(nèi)容編輯界面解決了這個(gè)問題。
管理界面不是為了網(wǎng)站的訪問者,而是為管理者準(zhǔn)備的。

創(chuàng)建一個(gè)管理員賬號(hào)

首先,我們得創(chuàng)建一個(gè)能登錄管理頁面的用戶。請(qǐng)運(yùn)行下面的命令:

...\> py manage.py createsuperuser

鍵入你想要使用的用戶名,然后按下回車鍵:

Username: admin

然后提示你輸入想要使用的郵件地址:

Email address: admin@example.com

最后一步是輸入密碼。你會(huì)被要求輸入兩次密碼,第二次的目的是為了確認(rèn)第一次輸入的確實(shí)是你想要的密碼。

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

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

Django 的管理界面默認(rèn)就是啟用的。讓我們啟動(dòng)開發(fā)服務(wù)器,看看它到底是什么樣的。

如果開發(fā)服務(wù)器未啟動(dòng),用以下命令啟動(dòng)它:

...\> py manage.py runserver

現(xiàn)在,打開瀏覽器,轉(zhuǎn)到你本地域名的 “/admin/” 目錄, -- 比如 http://127.0.0.1:8000/admin/ 。你應(yīng)該會(huì)看見管理員登錄界面:

admin01

因?yàn)榉g功能默認(rèn)是開啟的,如果你設(shè)置了 ?LANGUAGE_CODE?,登錄界面將顯示你設(shè)置的語言(如果 Django 有相應(yīng)的翻譯)。

進(jìn)入管理站點(diǎn)頁面

現(xiàn)在,試著使用你在上一步中創(chuàng)建的超級(jí)用戶來登錄。然后你將會(huì)看到 Django 管理頁面的索引頁:

admin02

你將會(huì)看到幾種可編輯的內(nèi)容:組和用戶。它們是由 ?django.contrib.auth? 提供的,這是 Django 開發(fā)的認(rèn)證框架。

向管理頁面中加入投票應(yīng)用

但是我們的投票應(yīng)用在哪呢?它沒在索引頁面里顯示。
只需要再做一件事:我們得告訴管理,問題 ?Question ?對(duì)象需要一個(gè)后臺(tái)接口。打開 ?polls/admin.py? 文件,把它編輯成下面這樣:

from django.contrib import admin

from .models import Question

admin.site.register(Question)

體驗(yàn)便捷的管理功能

現(xiàn)在我們向管理頁面注冊(cè)了問題 ?Question類。Django 知道它應(yīng)該被顯示在索引頁里:

admin03t

點(diǎn)擊 "Questions" ?,F(xiàn)在看到是問題 "Questions" 對(duì)象的列表 "change list" 。這個(gè)界面會(huì)顯示所有數(shù)據(jù)庫里的問題 Question 對(duì)象,你可以選擇一個(gè)來修改。這里現(xiàn)在有我們?cè)谏弦徊糠种袆?chuàng)建的 “What's up?” 問題。

admin04t

點(diǎn)擊 “What's up?” 來編輯這個(gè)問題(Question)對(duì)象:

admin05t

注意事項(xiàng):

  • 這個(gè)表單是從問題 ?Question ?模型中自動(dòng)生成的
  • 不同的字段類型(日期時(shí)間字段 ?DateTimeField ?、字符字段 ?CharField?)會(huì)生成對(duì)應(yīng)的 HTML 輸入控件。每個(gè)類型的字段都知道它們?cè)撊绾卧诠芾眄撁胬镲@示自己。
  • 每個(gè)日期時(shí)間字段 ?DateTimeField ?都有 JavaScript 寫的快捷按鈕。日期有轉(zhuǎn)到今天(Today)的快捷按鈕和一個(gè)彈出式日歷界面。時(shí)間有設(shè)為現(xiàn)在(Now)的快捷按鈕和一個(gè)列出常用時(shí)間的方便的彈出式列表。

頁面的底部提供了幾個(gè)選項(xiàng):

  • 保存(?Save?) - 保存改變,然后返回對(duì)象列表。
  • 保存并繼續(xù)編輯(?Save and continue editing?) - 保存改變,然后重新載入當(dāng)前對(duì)象的修改界面。
  • 保存并新增(?Save and add another?) - 保存改變,然后添加一個(gè)新的空對(duì)象并載入修改界面。
  • 刪除(?Delete?) - 顯示一個(gè)確認(rèn)刪除頁面。

如果顯示的 “發(fā)布日期(Date Published)” 和你在 教程 1 里創(chuàng)建它們的時(shí)間不一致,這意味著你可能沒有正確的設(shè)置 ?TIME_ZONE。改變?cè)O(shè)置,然后重新載入頁面看看是否顯示了正確的值。
通過點(diǎn)擊 “今天(Today)” 和 “現(xiàn)在(Now)” 按鈕改變 “發(fā)布日期(Date Published)”。然后點(diǎn)擊 “保存并繼續(xù)編輯(Save and add another)”按鈕。然后點(diǎn)擊右上角的 “歷史(History)”按鈕。你會(huì)看到一個(gè)列出了所有通過 Django 管理頁面對(duì)當(dāng)前對(duì)象進(jìn)行的改變的頁面,其中列出了時(shí)間戳和進(jìn)行修改操作的用戶名:

admin06t


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)