編寫你的第一個 Django 應(yīng)用,第 2 部分?這部分教程從 教程第 1 部分 結(jié)尾的地方繼續(xù)講起。我們將建立數(shù)據(jù)庫,創(chuàng)建您的第一個模型,并主要關(guān)注 Django 提供的自動生成的管理頁面。 數(shù)據(jù)庫配置?現(xiàn)在,打開 通常,這個配置文件使用 SQLite 作為默認數(shù)據(jù)庫。如果你不熟悉數(shù)據(jù)庫,或者只是想嘗試下 Django,這是最簡單的選擇。Python 內(nèi)置 SQLite,所以你無需安裝額外東西來使用它。當(dāng)你開始一個真正的項目時,你可能更傾向使用一個更具擴展性的數(shù)據(jù)庫,例如 PostgreSQL,避免中途切換數(shù)據(jù)庫這個令人頭疼的問題。 如果你想使用其他數(shù)據(jù)庫,你需要安裝合適的 database bindings ,然后改變設(shè)置文件中
如果你不使用 SQLite,則必須添加一些額外設(shè)置,比如 SQLite 以外的其它數(shù)據(jù)庫 如果你使用了 SQLite 以外的數(shù)據(jù)庫,請確認在使用前已經(jīng)創(chuàng)建了數(shù)據(jù)庫。你可以通過在你的數(shù)據(jù)庫交互式命令行中使用 " 另外,還要確保該數(shù)據(jù)庫用戶中提供 如果你使用 SQLite,那么你不需要在使用前做任何事——數(shù)據(jù)庫會在需要的時候自動創(chuàng)建。 編輯 此外,關(guān)注一下文件頭部的 通常,
這些應(yīng)用被默認啟用是為了給常規(guī)項目提供方便。 默認開啟的某些應(yīng)用需要至少一個數(shù)據(jù)表,所以,在使用他們之前需要在數(shù)據(jù)庫中創(chuàng)建一些表。請執(zhí)行以下命令: $ python manage.py migrate ...\> py manage.py migrate 這個 寫給極簡主義者 就像之前說的,為了方便大多數(shù)項目,我們默認激活了一些應(yīng)用,但并不是每個人都需要它們。如果你不需要某個或某些應(yīng)用,你可以在運行 創(chuàng)建模型?在 Django 里寫一個數(shù)據(jù)庫驅(qū)動的 Web 應(yīng)用的第一步是定義模型 - 也就是數(shù)據(jù)庫結(jié)構(gòu)設(shè)計和附加的其它元數(shù)據(jù)。 設(shè)計哲學(xué) 模型是真實數(shù)據(jù)的簡單明確的描述。它包含了儲存的數(shù)據(jù)所必要的字段和行為。Django 遵循 DRY Principle 。它的目標(biāo)是你只需要定義數(shù)據(jù)模型,然后其它的雜七雜八代碼你都不用關(guān)心,它們會自動從模型生成。 來介紹一下遷移 - 舉個例子,不像 Ruby On Rails,Django 的遷移代碼是由你的模型文件自動生成的,它本質(zhì)上只是個歷史記錄,Django 可以用它來進行數(shù)據(jù)庫的滾動更新,通過這種方式使其能夠和當(dāng)前的模型匹配。 在這個簡單的投票應(yīng)用中,需要創(chuàng)建兩個模型:問題 這些概念可以通過一個簡單的 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) 代碼非常直白。每個模型被表示為 每個字段都是 每個 你可以使用可選的選項來為 定義某些
注意在最后,我們使用 激活模型?上面的一小段用于創(chuàng)建模型的代碼給了 Django 很多信息,通過這些信息,Django 可以:
但是首先得把 設(shè)計哲學(xué) Django 應(yīng)用是“可插拔”的。你可以在多個項目中使用同一個應(yīng)用。除此之外,你還可以發(fā)布自己的應(yīng)用,因為它們并不會被綁定到當(dāng)前安裝的 Django 上。 為了在我們的工程中包含這個應(yīng)用,我們需要在配置類 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 項目會包含 $ python manage.py makemigrations polls ...\> py manage.py makemigrations polls 你將會看到類似于下面這樣的輸出: Migrations for 'polls': polls/migrations/0001_initial.py: - Create model Choice - Create model Question - Add field question to choice 通過運行 遷移是 Django 對于模型定義(也就是你的數(shù)據(jù)庫結(jié)構(gòu))的變化的儲存形式 - 沒那么玄乎,它們其實也只是一些你磁盤上的文件。如果你想的話,你可以閱讀一下你模型的遷移數(shù)據(jù),它被儲存在 Django 有一個自動執(zhí)行數(shù)據(jù)庫遷移并同步管理你的數(shù)據(jù)庫結(jié)構(gòu)的命令 - 這個命令是 $ python manage.py sqlmigrate polls 0001 ...\> py 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; 請注意以下幾點:
如果你感興趣,你也可以試試運行 現(xiàn)在,再次運行 $ 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 ...\> 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 這個 遷移是非常強大的功能,它能讓你在開發(fā)過程中持續(xù)的改變數(shù)據(jù)庫結(jié)構(gòu)而不需要重新刪除和創(chuàng)建表 - 它專注于使數(shù)據(jù)庫平滑升級而不會丟失數(shù)據(jù)。我們會在后面的教程中更加深入的學(xué)習(xí)這部分內(nèi)容,現(xiàn)在,你只需要記住,改變模型需要這三步:
數(shù)據(jù)庫遷移被分解成生成和應(yīng)用兩個命令是為了讓你能夠在代碼控制系統(tǒng)上提交遷移數(shù)據(jù)并使其能在多個應(yīng)用里使用;這不僅僅會讓開發(fā)更加簡單,也給別的開發(fā)者和生產(chǎn)環(huán)境中的使用帶來方便。 通過閱讀文檔 Django 后臺文檔 ,你可以獲得關(guān)于 初試 API?現(xiàn)在讓我們進入交互式 Python 命令行,嘗試一下 Django 為你創(chuàng)建的各種 API。通過以下命令打開 Python 命令行: $ python manage.py shell ...\> py manage.py shell 我們使用這個命令而不是簡單的使用 "Python" 是因為 當(dāng)你成功進入命令行后,來試試 database 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)>]> 等等。 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 給模型增加 注意:這些都是常規(guī)的 Python方法。讓我們添加一個自定義的方法,這只是為了演示: 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) 新加入的 保存文件然后通過 >>> 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() 閱讀 訪問關(guān)系對象 文檔可以獲取關(guān)于數(shù)據(jù)庫關(guān)系的更多內(nèi)容。想知道關(guān)于雙下劃線的更多用法,參見 查找字段 文檔。數(shù)據(jù)庫 API 的所有細節(jié)可以在 數(shù)據(jù)庫 API 參考 文檔中找到。 介紹 Django 管理頁面?設(shè)計哲學(xué) 為你的員工或客戶生成一個用戶添加,修改和刪除內(nèi)容的后臺是一項缺乏創(chuàng)造性和乏味的工作。因此,Django 全自動地根據(jù)模型創(chuàng)建后臺界面。 Django 產(chǎn)生于一個公眾頁面和內(nèi)容發(fā)布者頁面完全分離的新聞類站點的開發(fā)過程中。站點管理人員使用管理系統(tǒng)來添加新聞、事件和體育時訊等,這些添加的內(nèi)容被顯示在公眾頁面上。Django 通過為站點管理人員創(chuàng)建統(tǒng)一的內(nèi)容編輯界面解決了這個問題。 管理界面不是為了網(wǎng)站的訪問者,而是為管理者準(zhǔn)備的。 創(chuàng)建一個管理員賬號?首先,我們得創(chuàng)建一個能登錄管理頁面的用戶。請運行下面的命令: $ python manage.py createsuperuser ...\> py manage.py createsuperuser 鍵入你想要使用的用戶名,然后按下回車鍵: Username: admin 然后提示你輸入想要使用的郵件地址: Email address: admin@example.com 最后一步是輸入密碼。你會被要求輸入兩次密碼,第二次的目的是為了確認第一次輸入的確實是你想要的密碼。 Password: ********** Password (again): ********* Superuser created successfully. 啟動開發(fā)服務(wù)器?Django 的管理界面默認就是啟用的。讓我們啟動開發(fā)服務(wù)器,看看它到底是什么樣的。 如果開發(fā)服務(wù)器未啟動,用以下命令啟動它: $ python manage.py runserver ...\> py manage.py runserver 現(xiàn)在,打開瀏覽器,轉(zhuǎn)到你本地域名的 "/admin/" 目錄, -- 比如 "
因為 翻譯 功能默認是開著的,所以登錄界面可能會使用你的語言,取決于你瀏覽器的設(shè)置和 Django 是否擁有你語言的翻譯。 進入管理站點頁面?現(xiàn)在,試著使用你在上一步中創(chuàng)建的超級用戶來登錄。然后你將會看到 Django 管理頁面的索引頁: ![]() 你將會看到幾種可編輯的內(nèi)容:組和用戶。它們是由 向管理頁面中加入投票應(yīng)用?但是我們的投票應(yīng)用在哪呢?它沒在索引頁面里顯示。 只需要做一件事:我們得告訴管理頁面,問題 polls/admin.py?
from django.contrib import admin from .models import Question admin.site.register(Question) 體驗便捷的管理功能?現(xiàn)在我們向管理頁面注冊了問題 ![]() 點擊 "Questions" ?,F(xiàn)在看到是問題 "Questions" 對象的列表 "change list" 。這個界面會顯示所有數(shù)據(jù)庫里的問題 Question 對象,你可以選擇一個來修改。這里現(xiàn)在有我們在上一部分中創(chuàng)建的 “What's up?” 問題。 ![]() 點擊 “What's up?” 來編輯這個問題(Question)對象: ![]() 注意事項:
頁面的底部提供了幾個選項:
如果顯示的 “發(fā)布日期(Date Published)” 和你在 教程 1 里創(chuàng)建它們的時間不一致,這意味著你可能沒有正確的設(shè)置 通過點擊 “今天(Today)” 和 “現(xiàn)在(Now)” 按鈕改變 “發(fā)布日期(Date Published)”。然后點擊 “保存并繼續(xù)編輯(Save and add another)”按鈕。然后點擊右上角的 “歷史(History)”按鈕。你會看到一個列出了所有通過 Django 管理頁面對當(dāng)前對象進行的改變的頁面,其中列出了時間戳和進行修改操作的用戶名: ![]() 當(dāng)你熟悉了數(shù)據(jù)庫 API 之后,你就可以開始閱讀 教程第 3 部分 ,下一部分我們將會學(xué)習(xí)如何為投票應(yīng)用添加更多視圖。 |
|
來自: 寧靜致遠oj1kn5 > 《官網(wǎng)》