這篇文章運(yùn)用簡(jiǎn)單易懂的例子給大家介紹Django項(xiàng)目怎么實(shí)現(xiàn)模型與管理后臺(tái),代碼非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對(duì)大家能有所幫助。
創(chuàng)新互聯(lián)公司2013年至今,先為南岸等服務(wù)建站,南岸等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為南岸企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。
一、數(shù)據(jù)庫(kù)配置
打開(kāi)mysite/settings.py配置文件,這是整個(gè)Django項(xiàng)目的設(shè)置中心。Django默認(rèn)使用SQLite數(shù)據(jù)庫(kù),因?yàn)镻ython源生支持SQLite數(shù)據(jù)庫(kù),所以你無(wú)須安裝任何程序,就可以直接使用它。當(dāng)然,如果你是在創(chuàng)建一個(gè)實(shí)際的項(xiàng)目,可以使用類似PostgreSQL的數(shù)據(jù)庫(kù),避免以后數(shù)據(jù)庫(kù)遷移的相關(guān)問(wèn)題。
# mysite/settings.py # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } }
如果你想使用其他的數(shù)據(jù)庫(kù),請(qǐng)先安裝相應(yīng)的數(shù)據(jù)庫(kù)操作模塊,并將settings文件中DATABASES位置的’default’的鍵值進(jìn)行相應(yīng)的修改,用于連接你的數(shù)據(jù)庫(kù)。其中:
ENGINE(引擎):可以是django.db.backends.sqlite3、django.db.backends.postgresql、django.db.backends.MySQL、django.db.backends.oracle,當(dāng)然其它的也行。
NAME(名稱):類似Mysql數(shù)據(jù)庫(kù)管理系統(tǒng)中用于保存項(xiàng)目?jī)?nèi)容的數(shù)據(jù)庫(kù)的名字。如果你使用的是默認(rèn)的SQLite,那么數(shù)據(jù)庫(kù)將作為一個(gè)文件將存放在你的本地機(jī)器內(nèi),此時(shí)的NAME應(yīng)該是這個(gè)文件的完整絕對(duì)路徑包括文件名,默認(rèn)值os.path.join(BASE_DIR, ’db.sqlite3’),將把該文件儲(chǔ)存在你的項(xiàng)目目錄下。
如果你不是使用默認(rèn)的SQLite數(shù)據(jù)庫(kù),那么一些諸如USER,PASSWORD和HOST的參數(shù)必須手動(dòng)指定!下面給出一個(gè)基于pymysql操作Mysql數(shù)據(jù)庫(kù)的例子,更多細(xì)節(jié)參考后續(xù)的數(shù)據(jù)庫(kù)章節(jié)。
# mysite/settings.py# Database# https://docs.djangoproject.com/en/1.11/ref/settings/#databasesimport pymysql # 一定要添加這兩行!通過(guò)pip install pymysql! pymysql.install_as_MySQLdb()DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'mysite', 'HOST': '192.168.1.1', 'USER': 'root', 'PASSWORD': 'pwd', 'PORT': '3306', }}
注意:
在使用非SQLite的數(shù)據(jù)庫(kù)時(shí),請(qǐng)務(wù)必預(yù)先在數(shù)據(jù)庫(kù)管理系統(tǒng)的提示符交互模式下創(chuàng)建數(shù)據(jù)庫(kù),你可以使用命令:CREATE DATABASE database_name;。Django不會(huì)自動(dòng)幫你做這一步工作。確保你在settings文件中提供的數(shù)據(jù)庫(kù)用戶具有創(chuàng)建數(shù)據(jù)庫(kù)表的權(quán)限,因?yàn)樵诮酉聛?lái)的教程中,我們需要自動(dòng)創(chuàng)建一個(gè)test數(shù)據(jù)表。(在實(shí)際項(xiàng)目中也需要確認(rèn)這一條要求。)如果你使用的是SQLite,那么你無(wú)需做任何預(yù)先配置,直接使用就可以了。
在修改settings文件時(shí),請(qǐng)順便將TIME_ZONE設(shè)置為國(guó)內(nèi)所在的時(shí)區(qū)Asia/Shanghai。
同時(shí),請(qǐng)注意settings文件中頂部的INSTALLED_APPS設(shè)置項(xiàng)。它列出了所有的項(xiàng)目中被激活的Django應(yīng)用(app)。你必須將你自定義的app注冊(cè)在這里。每個(gè)應(yīng)用可以被多個(gè)項(xiàng)目使用,并且可以打包和分發(fā)給其他人在他們的項(xiàng)目中使用。
默認(rèn)情況,INSTALLED_APPS中會(huì)自動(dòng)包含下列條目,它們都是Django自動(dòng)生成的:
django.contrib.admin:admin管理后臺(tái)站點(diǎn)django.contrib.auth:身份認(rèn)證系統(tǒng)django.contrib.contenttypes:內(nèi)容類型框架django.contrib.sessions:會(huì)話框架django.contrib.messages:消息框架django.contrib.staticfiles:靜態(tài)文件管理框架
上面的一些應(yīng)用也需要建立一些數(shù)據(jù)庫(kù)表,所以在使用它們之前我們要在數(shù)據(jù)庫(kù)中創(chuàng)建這些表。使用下面的命令創(chuàng)建數(shù)據(jù)表:
$ python manage.py migrate
migrate命令將遍歷INSTALLED_APPS設(shè)置中的所有項(xiàng)目,在數(shù)據(jù)庫(kù)中創(chuàng)建對(duì)應(yīng)的表,并打印出每一條動(dòng)作信息。如果你感興趣,可以在你的數(shù)據(jù)庫(kù)命令行下輸入:\dt (PostgreSQL)、 SHOW TABLES;(MySQL)或 .schema(SQLite) 來(lái)列出 Django 所創(chuàng)建的表。
提示:對(duì)于極簡(jiǎn)主義者,你完全可以在INSTALLED_APPS內(nèi)注釋掉任何或者全部的Django提供的通用應(yīng)用。這樣,migrate也不會(huì)再創(chuàng)建對(duì)應(yīng)的數(shù)據(jù)表。
二、創(chuàng)建模型
現(xiàn)在,我們來(lái)定義模型model,模型本質(zhì)上就是數(shù)據(jù)庫(kù)表的布局,再附加一些元數(shù)據(jù)。
Django通過(guò)自定義Python類的形式來(lái)定義具體的模型,每個(gè)模型的物理存在方式就是一個(gè)Python的類Class,每個(gè)模型代表數(shù)據(jù)庫(kù)中的一張表,每個(gè)類的實(shí)例代表數(shù)據(jù)表中的一行數(shù)據(jù),類中的每個(gè)變量代表數(shù)據(jù)表中的一列字段。Django通過(guò)模型,將Python代碼和數(shù)據(jù)庫(kù)操作結(jié)合起來(lái),實(shí)現(xiàn)對(duì)SQL查詢語(yǔ)言的封裝。也就是說(shuō),你可以不會(huì)管理數(shù)據(jù)庫(kù),可以不會(huì)SQL語(yǔ)言,你同樣能通過(guò)Python的代碼進(jìn)行數(shù)據(jù)庫(kù)的操作。Django通過(guò)ORM對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作,奉行代碼優(yōu)先的理念,將Python程序員和數(shù)據(jù)庫(kù)管理員進(jìn)行分工解耦。
在這個(gè)簡(jiǎn)單的投票應(yīng)用中,我們將創(chuàng)建兩個(gè)模型:Question和Choice。Question包含一個(gè)問(wèn)題和一個(gè)發(fā)布日期。Choice包含兩個(gè)字段:該選項(xiàng)的文本描述和該選項(xiàng)的投票數(shù)。每一條Choice都關(guān)聯(lián)到一個(gè)Question。這些都是由Python的類來(lái)體現(xiàn),編寫的全是Python的代碼,不接觸任何SQL語(yǔ)句?,F(xiàn)在,編輯polls/models.py文件,具體代碼如下:
# polls/models.pyfrom django.db import modelsclass 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è)類都是django.db.models.Model的子類。每一個(gè)字段都是Field類的一個(gè)實(shí)例,例如用于保存字符數(shù)據(jù)的CharField和用于保存時(shí)間類型的DateTimeField,它們告訴Django每一個(gè)字段保存的數(shù)據(jù)類型。
每一個(gè)Field實(shí)例的名字就是字段的名字(如: question_text 或者 pub_date )。在你的Python代碼中會(huì)使用這個(gè)值,你的數(shù)據(jù)庫(kù)也會(huì)將這個(gè)值作為表的列名。
你也可以在每個(gè)Field中使用一個(gè)可選的第一位置參數(shù)用于提供一個(gè)人類可讀的字段名,讓你的模型更友好,更易讀,并且將被作為文檔的一部分來(lái)增強(qiáng)代碼的可讀性。
一些Field類必須提供某些特定的參數(shù)。例如CharField需要你指定max_length。這不僅是數(shù)據(jù)庫(kù)結(jié)構(gòu)的需要,同樣也用于數(shù)據(jù)驗(yàn)證功能。
有必填參數(shù),當(dāng)然就會(huì)有可選參數(shù),比如在votes里我們將其默認(rèn)值設(shè)為0.
最后請(qǐng)注意,我們使用ForeignKey定義了一個(gè)外鍵關(guān)系。它告訴Django,每一個(gè)Choice關(guān)聯(lián)到一個(gè)對(duì)應(yīng)的Question(注意要將外鍵寫在‘多’的一方)。Django支持通用的數(shù)據(jù)關(guān)系:一對(duì)一,多對(duì)一和多對(duì)多。
三、啟用模型
上面的代碼看著有點(diǎn)少,其實(shí)包含了大量的信息,據(jù)此,Django會(huì)做下面兩件事:
創(chuàng)建該app對(duì)應(yīng)的數(shù)據(jù)庫(kù)表結(jié)構(gòu)為Question和Choice對(duì)象創(chuàng)建基于Python的數(shù)據(jù)庫(kù)訪問(wèn)API
但是,首先我們得先告訴Django項(xiàng)目,我們要使用投票app。
要將應(yīng)用添加到項(xiàng)目中,需要在INSTALLED_APPS設(shè)置中增加指向該應(yīng)用的配置文件的鏈接。對(duì)于本例的投票應(yīng)用,它的配置類文件PollsConfig是polls/apps.py,所以它的點(diǎn)式路徑為polls.apps.PollsConfig。我們需要在INSTALLED_APPS中,將該路徑添加進(jì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', ]
實(shí)際上,在多數(shù)情況下,我們簡(jiǎn)寫成‘polls’就可以了:
# mysite/settings.py INSTALLED_APPS = [ 'polls', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
現(xiàn)在Django已經(jīng)知道你的投票應(yīng)用的存在了,并把它加入了項(xiàng)目大家庭。
我們需要再運(yùn)行下一個(gè)命令:
$ python manage.py makemigrations polls
你會(huì)看到類似下面的提示:
Migrations for 'polls': polls/migrations/0001_initial.py: - Create model Choice - Create model Question - Add field question to choice
通過(guò)運(yùn)行makemigrations命令,Django 會(huì)檢測(cè)你對(duì)模型文件的修改,也就是告訴Django你對(duì)模型有改動(dòng),并且你想把這些改動(dòng)保存為一個(gè)“遷移(migration)”。
migrations是Django保存模型修改記錄的文件,這些文件保存在磁盤上。在例子中,它就是polls/migrations/0001_initial.py,你可以打開(kāi)它看看,里面保存的都是人類可讀并且可編輯的內(nèi)容,方便你隨時(shí)手動(dòng)修改。
接下來(lái)有一個(gè)叫做migrate的命令將對(duì)數(shù)據(jù)庫(kù)執(zhí)行真正的遷移動(dòng)作。但是在此之前,讓我們先看看在migration的時(shí)候?qū)嶋H執(zhí)行的SQL語(yǔ)句是什么。有一個(gè)叫做sqlmigrate的命令可以展示SQL語(yǔ)句,例如:
$ python manage.py sqlmigrate polls 0001
你將會(huì)看到如下類似的文本(經(jīng)過(guò)適當(dāng)?shù)母袷秸{(diào)整,方便閱讀):
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)注意:
實(shí)際的輸出內(nèi)容將取決于您使用的數(shù)據(jù)庫(kù)會(huì)有所不同。上面的是PostgreSQL的輸出。表名是自動(dòng)生成的,通過(guò)組合應(yīng)用名 (polls) 和小寫的模型名question和choice 。 ( 你可以重寫此行為。)主鍵 (IDs) 是自動(dòng)添加的。( 你也可以重寫此行為。)按照慣例,Django 會(huì)在外鍵字段名上附加 "_id" 。 (你仍然可以重寫此行為。)生成SQL語(yǔ)句時(shí)針對(duì)你所使用的數(shù)據(jù)庫(kù),會(huì)為你自動(dòng)處理特定于數(shù)據(jù)庫(kù)的字段,例如 auto_increment (MySQL), serial (PostgreSQL), 或integer primary key (SQLite) 。 在引用字段名時(shí)也是如此 – 比如使用雙引號(hào)或單引號(hào)。這些SQL命令并沒(méi)有在你的數(shù)據(jù)庫(kù)中實(shí)際運(yùn)行,它只是在屏幕上顯示出來(lái),以便讓你了解Django真正執(zhí)行的是什么。
如果你感興趣,也可以運(yùn)行python manage.py check命令,它將檢查項(xiàng)目中的錯(cuò)誤,并不實(shí)際進(jìn)行遷移或者鏈接數(shù)據(jù)庫(kù)的操作。
現(xiàn)在,我們可以運(yùn)行migrate命令,在數(shù)據(jù)庫(kù)中進(jì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
migrate命令對(duì)所有還未實(shí)施的遷移記錄進(jìn)行操作,本質(zhì)上就是將你對(duì)模型的修改體現(xiàn)到數(shù)據(jù)庫(kù)中具體的表上面。Django通過(guò)一張叫做django_migrations的表,記錄并跟蹤已經(jīng)實(shí)施的migrate動(dòng)作,通過(guò)對(duì)比獲得哪些migrations尚未提交。
migrations的功能非常強(qiáng)大,允許你隨時(shí)修改你的模型,而不需要?jiǎng)h除或者新建你的數(shù)據(jù)庫(kù)或數(shù)據(jù)表,在不丟失數(shù)據(jù)的同時(shí),實(shí)時(shí)動(dòng)態(tài)更新數(shù)據(jù)庫(kù)。我們將在后面的章節(jié)對(duì)此進(jìn)行深入的闡述,但是現(xiàn)在,只需要記住修改模型時(shí)的操作分三步:
在models.py中修改模型;運(yùn)行python manage.py makemigrations為改動(dòng)創(chuàng)建遷移記錄;運(yùn)行python manage.py migrate,將操作同步到數(shù)據(jù)庫(kù)。
之所以要將創(chuàng)建和實(shí)施遷移的動(dòng)作分成兩個(gè)命令兩步走是因?yàn)槟阋苍S要通過(guò)版本控制系統(tǒng)(例如github,svn)提交你的項(xiàng)目代碼,如果沒(méi)有一個(gè)中間過(guò)程的保存文件(migrations),那么github如何知道以及記錄、同步、實(shí)施你所進(jìn)行過(guò)的模型修改動(dòng)作呢?畢竟,github不和數(shù)據(jù)庫(kù)直接打交道,也沒(méi)法和你本地的數(shù)據(jù)庫(kù)通信。但是分開(kāi)之后,你只需要將你的migration文件(例如上面的0001)上傳到github,它就會(huì)知道一切。
四、使用模型的API
下面,讓我們進(jìn)入Python交互環(huán)境,嘗試使用Django提供的數(shù)據(jù)庫(kù)訪問(wèn)API。要進(jìn)入Python的shell,請(qǐng)輸入命令:
$ python manage.py shell
相比較直接輸入“python”命令的方式進(jìn)入Python環(huán)境,調(diào)用manage.py參數(shù)能將DJANGO_SETTINGS_MODULE環(huán)境變量導(dǎo)入,它將自動(dòng)按照mysite/settings.py中的設(shè)置,配置好你的python shell環(huán)境,這樣,你就可以導(dǎo)入和調(diào)用任何你項(xiàng)目?jī)?nèi)的模塊了。
或者你也可以這樣,先進(jìn)入一個(gè)純凈的python shell環(huán)境,然后啟動(dòng)Django,具體如下:
>>> import django >>> django.setup()
當(dāng)你進(jìn)入shell后,嘗試一下下面的API吧:
>>> from polls.models import Question, Choice # 導(dǎo)入我們寫的模型類 # 現(xiàn)在系統(tǒng)內(nèi)還沒(méi)有questions對(duì)象 >>> Question.objects.all() <QuerySet []> # 創(chuàng)建一個(gè)新的question對(duì)象 # Django推薦使用timezone.now()代替python內(nèi)置的datetime.datetime.now() # 這個(gè)timezone就來(lái)自于Django的依賴庫(kù)pytz from django.utils import timezone >>> q = Question(question_text="What's new?", pub_date=timezone.now()) # 你必須顯式的調(diào)用save()方法,才能將對(duì)象保存到數(shù)據(jù)庫(kù)內(nèi) >>> q.save() # 默認(rèn)情況,你會(huì)自動(dòng)獲得一個(gè)自增的名為id的主鍵 >>> q.id 1 # 通過(guò)python的屬性調(diào)用方式,訪問(wèn)模型字段的值 >>> q.question_text "What's new?" >>> q.pub_date datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>) # 通過(guò)修改屬性來(lái)修改字段的值,然后顯式的調(diào)用save方法進(jìn)行保存。 >>> q.question_text = "What's up?" >>> q.save() # objects.all() 用于查詢數(shù)據(jù)庫(kù)內(nèi)的所有questions >>> Question.objects.all() <QuerySet [<Question: Question object>]>
這里等一下:上面的<Question: Question object>是一個(gè)不可讀的內(nèi)容展示,你無(wú)法從中獲得任何直觀的信息,為此我們需要一點(diǎn)小技巧,讓Django在打印對(duì)象時(shí)顯示一些我們指定的信息。
返回polls/models.py文件,修改一下question和Choice這兩個(gè)類,代碼如下:
from django.db import modelsclass Question(models.Model): # ... def __str__(self): return self.question_textclass Choice(models.Model): # ... def __str__(self): return self.choice_text
這個(gè)技巧不但對(duì)你打印對(duì)象時(shí)很有幫助,在你使用Django的admin站點(diǎn)時(shí)也同樣有幫助。
另外,這里我們自定義一個(gè)模型的方法,用于判斷問(wèn)卷是否最近時(shí)間段內(nèi)發(fā)布度的:
import datetimefrom django.db import modelsfrom django.utils import timezoneclass Question(models.Model): # ... def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
請(qǐng)注意上面分別導(dǎo)入了兩個(gè)關(guān)于時(shí)間的模塊,一個(gè)是python內(nèi)置的datetime一個(gè)是Django工具包提供的timezone。
保存修改后,我們重新啟動(dòng)一個(gè)新的python shell,再來(lái)看看其他的API:
>>> from polls.models import Question, Choice# 先看看__str__()的效果,直觀多了吧? >>> Question.objects.all()<QuerySet [<Question: What's up?>]># Django提供了大量的關(guān)鍵字參數(shù)查詢API >>> Question.objects.filter(id=1)<QuerySet [<Question: What's up?>] >>>> Question.objects.filter(question_text__startswith='What')<QuerySet [<Question: What's up?>]> # 獲取今年發(fā)布的問(wèn)卷 >>> from django.utils import timezone >>> current_year = timezone.now().year >>> Question.objects.get(pub_date__year=current_year)<Question: What's up?># 查詢一個(gè)不存在的ID,會(huì)彈出異常 >>> Question.objects.get(id=2)Traceback (most recent call last): ...DoesNotExist: Question matching query does not exist. # Django為主鍵查詢提供了一個(gè)縮寫:pk。下面的語(yǔ)句和Question.objects.get(id=1)效果一樣. >>> Question.objects.get(pk=1)<Question: What's up?># 看看我們自定義的方法用起來(lái)怎么樣 >>> q = Question.objects.get(pk=1) >>> q.was_published_recently()True# 讓我們?cè)囋囍麈I查詢 >>> q = Question.objects.get(pk=1)# 顯示所有與q對(duì)象有關(guān)系的choice集合,目前是空的,還沒(méi)有任何關(guān)聯(lián)對(duì)象。 >>> q.choice_set.all()<QuerySet []># 創(chuàng)建3個(gè)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對(duì)象可通過(guò)API訪問(wèn)和他們關(guān)聯(lián)的Question對(duì)象 >>> c.question<Question: What's up?># 同樣的,Question對(duì)象也可通過(guò)API訪問(wèn)關(guān)聯(lián)的Choice對(duì)象 >>> q.choice_set.all()<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>] >>>> q.choice_set.count()3# API會(huì)自動(dòng)進(jìn)行連表操作,通過(guò)雙下劃線分割關(guān)系對(duì)象。連表操作可以無(wú)限多級(jí),一層一層的連接。 # 下面是查詢所有的Choices,它所對(duì)應(yīng)的Question的發(fā)布日期是今年。(重用了上面的current_year結(jié)果) >>> Choice.objects.filter(question__pub_date__year=current_year) <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]># 使用delete方法刪除對(duì)象 >>> c = q.choice_set.filter(choice_text__startswith='Just hacking')>>> c.delete()
關(guān)于模型的使用就暫時(shí)先介紹這么多。這部分內(nèi)容是Django項(xiàng)目的核心,也是動(dòng)態(tài)網(wǎng)站與數(shù)據(jù)庫(kù)交互的核心,對(duì)于初學(xué)者,再難理解也要理解。
五、admin后臺(tái)管理站點(diǎn)
很多時(shí)候,我們不光要開(kāi)發(fā)針對(duì)客戶使用的前端頁(yè)面,還要給后臺(tái)管理人員提供相應(yīng)的管理界面。但是大多數(shù)時(shí)候?yàn)槟愕膱F(tuán)隊(duì)或客戶編寫用于增加、修改和刪除內(nèi)容的后臺(tái)管理站點(diǎn)是一件非常乏味的工作并且沒(méi)有多少創(chuàng)造性,而且也需要花不少的時(shí)間和精力。Django最大的優(yōu)點(diǎn)之一,就是體貼的為你提供了一個(gè)基于項(xiàng)目model創(chuàng)建的一個(gè)后臺(tái)管理站點(diǎn)admin。這個(gè)界面只給站點(diǎn)管理員使用,并不對(duì)大眾開(kāi)放。雖然admin的界面可能不是那么美觀,功能不是那么強(qiáng)大,內(nèi)容不一定符合你的要求,但是它是免費(fèi)的、現(xiàn)成的,并且還是可定制的,有完善的幫助文檔,那么,你還要什么自行車?
1. 創(chuàng)建管理員用戶
首先,我們需要通過(guò)下面的命令,創(chuàng)建一個(gè)可以登錄admin站點(diǎn)的用戶:
$ python manage.py createsuperuser
輸入用戶名:
Username: admin
輸入郵箱地址:
Email address: xxx@xxx.xxx
輸入密碼:
Password: **********
Password (again): *********
Superuser created successfully.
注意:Django1.10版本后,超級(jí)用戶的密碼要求具備一定的復(fù)雜性,如果密碼強(qiáng)度不夠,Django會(huì)提示你,但是可以強(qiáng)制通過(guò)。
2. 啟動(dòng)開(kāi)發(fā)服務(wù)器
服務(wù)器啟動(dòng)后,在瀏覽器訪問(wèn)http://127.0.0.1:8000/admin/。你就能看到admin的登陸界面了:
(下面的路由操作可選)
在實(shí)際環(huán)境中,為了站點(diǎn)的安全性,我們一般不能將管理后臺(tái)的url隨便暴露給他人,不能用/admin/這么簡(jiǎn)單的路徑。
打開(kāi)根url路由文件mysite/urls.py,修改其中admin.site.urls對(duì)應(yīng)的表達(dá)式,換成你想要的,比如:
from django.contrib import admin from django.urls import pathurlpatterns = [ path('polls/', include('polls.urls')), path('control/', admin.site.urls),]
這樣,我們必須訪問(wèn)http://127.0.0.1:8000/control/才能進(jìn)入admin界面。
3. 進(jìn)入admin站點(diǎn)
利用剛才建立的admin賬戶,登陸admin,你將看到如下的界面:
當(dāng)前只有兩個(gè)可編輯的內(nèi)容:groups和users。它們是django.contrib.auth模塊提供的身份認(rèn)證框架。
4. 在admin中注冊(cè)投票應(yīng)用
現(xiàn)在還無(wú)法看到投票應(yīng)用,必須先在admin中進(jìn)行注冊(cè),告訴admin站點(diǎn),請(qǐng)將polls的模型加入站點(diǎn)內(nèi),接受站點(diǎn)的管理。
打開(kāi)polls/admin.py文件,加入下面的內(nèi)容:
from django.contrib import admin from .models import Questionadmin.site.register(Question)
4. admin站點(diǎn)的主要功能
注冊(cè)question模型后,刷新admin頁(yè)面就能看到Question欄目了。
點(diǎn)擊“Questions”,進(jìn)入questions的修改列表頁(yè)面。這個(gè)頁(yè)面會(huì)顯示所有的數(shù)據(jù)庫(kù)內(nèi)的questions對(duì)象,你可以在這里對(duì)它們進(jìn)行修改。看到下面的“What’s up?”了么?它就是我們先前創(chuàng)建的一個(gè)question對(duì)象,并且通過(guò)__str__方法的幫助,顯示了較為直觀的信息,而不是一個(gè)冷冰冰的對(duì)象類型名稱。
下面,點(diǎn)擊What’s up?進(jìn)入編輯界面:
這里需要注意的是:
頁(yè)面中的表單是由Question模型自動(dòng)生成的。不同的模型字段類型(DateTimeField, CharField)會(huì)表現(xiàn)為不同的HTML input框類型。每一個(gè)DateTimeField都會(huì)自動(dòng)生成一個(gè)可點(diǎn)擊鏈接。日期是Today,并有一個(gè)日歷彈出框;時(shí)間是Now,并有一個(gè)通用的時(shí)間輸入列表框。
在頁(yè)面的底部,則是一些可選項(xiàng)按鈕:
delete:彈出一個(gè)刪除確認(rèn)頁(yè)面save and add another:保存當(dāng)前修改,并加載一個(gè)新的空白的當(dāng)前類型對(duì)象的表單。save and continue editing:保存當(dāng)前修改,并重新加載該對(duì)象的編輯頁(yè)面。save:保存修改,返回當(dāng)前對(duì)象類型的列表頁(yè)面。
如果Date published字段的值和你在前面教程創(chuàng)建它的時(shí)候不一致,可能是你沒(méi)有正確的配置TIME_ZONE,在國(guó)內(nèi),通常是8個(gè)小時(shí)的時(shí)間差別。修改TIME_ZONE配置并重新加載頁(yè)面,就能顯示正確的時(shí)間了。
在頁(yè)面的右上角,點(diǎn)擊History按鈕,你會(huì)看到你對(duì)當(dāng)前對(duì)象的所有修改操作都在這里有記錄,包括修改時(shí)間和操作人員,如下圖所示:
關(guān)于Django項(xiàng)目怎么實(shí)現(xiàn)模型與管理后臺(tái)就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。
當(dāng)前文章:Django項(xiàng)目怎么實(shí)現(xiàn)模型與管理后臺(tái)
網(wǎng)站路徑:http://jinyejixie.com/article36/jpcdpg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、定制網(wǎng)站、網(wǎng)站排名、做網(wǎng)站、網(wǎng)站制作、微信小程序
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)