Django筆記03-數(shù)據(jù)庫與數(shù)據(jù)模型

數(shù)據(jù)庫與數(shù)據(jù)模型

django框架的設(shè)計也采用了MVC模式送朱,但是基于MVC模式卻更注重模型(Model)娘荡、模板(Template)、視圖(View)驶沼。通過編寫數(shù)據(jù)模型(Model)來完成對所有數(shù)據(jù)有關(guān)的事物炮沐,包括數(shù)據(jù)庫中數(shù)據(jù)的存取等操作。

數(shù)據(jù)庫

?Mysql回怜、SQLserver 2008大年、sqlite3 等數(shù)據(jù)庫都可以在 django 中使用,而默認(rèn)情況下玉雾,django 使用的是輕量級的sqlite3翔试,在項(xiàng)目配置文件中可以進(jìn)行數(shù)據(jù)庫配置

# fbckf/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
} 

?而作為一個小型個人博客,使用 sqlite3 這個數(shù)據(jù)庫就已經(jīng)綽綽有余了复旬,所以不用去更改配置文件

博客數(shù)據(jù)

?博客主要是發(fā)布文章垦缅,文章中包含很多信息,比如標(biāo)題驹碍、作者壁涎、類別、評論等志秃,而類別和評論又包括了各自的信息粹庞。將數(shù)據(jù)分為以下兩部分,也就是洽损,我們將在數(shù)據(jù)庫中建立兩張表庞溜,每一部分中的信息就是各自表中的字段。

1.文章

標(biāo)題 作者 類別 內(nèi)容 摘要 創(chuàng)建時間 喜歡人數(shù)
《絕望》 fbckf 散文 絕望啊... 絕望... 2018-6-2 999+
《白云謠》 先秦詩人 詩詞 白云在天... 白云在天... 2018-6-8 9999+

2.類別

名稱 簡介
散文 散文是一種抒發(fā)作者真情實(shí)感碑定、寫作方式靈活的記敘類文學(xué)體裁流码。
詩詞 詩詞,是指以古體詩延刘、近體詩和格律詞為代表的中國古代傳統(tǒng)詩歌漫试。

之所以要將類別和評論從文章中分離出來形成另的表格,是因?yàn)檫@樣可以避免數(shù)據(jù)庫中數(shù)據(jù)的重復(fù)存儲

數(shù)據(jù)庫模型

?之前所說過碘赖,需要在數(shù)據(jù)庫中創(chuàng)建三張表驾荣,用來存儲博客的各種數(shù)據(jù)普泡,創(chuàng)建的表就如之前所示的表格一樣播掷。一般情況下對數(shù)據(jù)庫的 SQL語句 不熟悉的話,在進(jìn)行數(shù)據(jù)庫操作時是比較頭疼的撼班,幸運(yùn)的是歧匈,django 已經(jīng)將 SQL語句 轉(zhuǎn)換成相對應(yīng)的 python 語言,只需要在 blog/models.py 中編寫相對應(yīng)的 python 代碼就好了砰嘁,其中類對應(yīng)數(shù)據(jù)庫中的表格件炉,類中的屬性則對應(yīng)數(shù)據(jù)庫中的字段
數(shù)據(jù)

編寫數(shù)據(jù)模型代碼

    # blog/models.py
    from django.db import models
    # auth是django內(nèi)置的一個應(yīng)用
    from django.contrib.auth.models import User
    
    # 對應(yīng)數(shù)據(jù)庫中類別的表勘究,類名 Category 就是表的名稱
    # 繼承了models.Model
    class Category(models.Model):
        # 屬性 name 是表中的名稱字段, name 是簡單的字符串所以使用CharField()類型
        # max_length=20 表示該字段最長為20字符斟冕,unique=True 表示該字段具有的唯一性
        name = models.CharField(max_length=20, unique=True)
        # 屬性instructions 對應(yīng)簡介字段口糕,因?yàn)?instructions 是文本,所以使用TextField()類型
        # default=“” 表示該字段默認(rèn)內(nèi)容為空
        instructions = models.TextField(max_length=100, default="")
        
    
    class Article(models.Model):
        title = models.CharField(max_length=50, unique=True)
        # 一個作者有多篇文章磕蛇,但是一篇文章只有一個作者走净,這是一對多的關(guān)系,所以使用 ForeignKey()類型
        # ForeignKey() 將 注冊的用戶 User 和文章關(guān)聯(lián)起來
        # on_delete=models.CASCADE 表示當(dāng)刪除該用戶時孤里,該用戶關(guān)聯(lián)的文章也會一并刪除
        # null=True 表示允許為空 比如從別的平臺轉(zhuǎn)發(fā)文章
        author = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
        category = models.ForeignKey(Category, null=True, on_delete=models.CASCADE)
        body = models.TextField()
        abstract = models.TextField(max_length=50, default="")
        # create_time 是時間伏伯,所以使用 DateTimeField()類型
        # auto_now=True 表示自動添加該字段的值
        create_time = models.DateTimeField(auto_now=True)
        # PositiveIntegerField() 只允許正整數(shù)和0,因?yàn)閘ikes字段不為負(fù)數(shù)和小數(shù)捌袜,所以使用該類型
        likes = models.PositiveIntegerField(default=0)
  • django 內(nèi)置的應(yīng)用 auth(django.contrib.auth)说搅,負(fù)責(zé)整個網(wǎng)站的用戶注冊、登陸等功能虏等,而 User 是該應(yīng)用中用戶的模型弄唧,就像 Category 類一樣,在這里導(dǎo)入后與文章關(guān)聯(lián)霍衫。

  • 在編寫模型代碼時候引,需要根據(jù)字段的類型選擇對應(yīng)的字段類型函數(shù),常用的有字符串類型(CharField)敦跌、文本類型(TextField)澄干、日期類型(DateField、DateTimeField)柠傍、郵箱(EmailField)麸俘、整數(shù)類型(IntegerField)等。

  • article 與 category惧笛、author是一對多的關(guān)聯(lián)關(guān)系所以使用 ForeignKey()關(guān)聯(lián)類型从媚,多對多的關(guān)聯(lián)關(guān)系是 MangToManyFiled()。

  • 評論建立另外一個應(yīng)用來完成患整。

數(shù)據(jù)庫遷移

?完成模型代碼編寫事情后還沒有結(jié)束拜效,那只是單純的寫好 python 代碼,就像只是寫策劃書各谚,還沒有真正去執(zhí)行紧憾,所以還需要告訴 django,根據(jù)編寫在models.py中的代碼嘲碧,去執(zhí)行相應(yīng)的 SQL語句稻励。

    $ python manage.py makemigrations
    Migrations for 'blog':
      blog/migrations/0001_initial.py
        - Create model Article
        - Create model Category
        - Add field category to article
    
    $ python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, blog, contenttypes, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying blog.0001_initial... OK
      Applying sessions.0001_initial... OK

?執(zhí)行以上命令之后父阻,在查看一下項(xiàng)目的變化

    $ tree fbckf
    fbckf
    ├── blog
    │     ├── admin.py
    │     ├── apps.py
    │     ├── __init__.py
    │     ├── migrations
    │     │     ├── 0001_initial.py
    │     │     ├── __init__.py
    │     │     └── __pycache__
    │     │             ├── 0001_initial.cpython-35.pyc
    │     │             └── __init__.cpython-35.pyc
    │     ├── models.py
    │     ├── __pycache__
    │     │       ├── admin.cpython-35.pyc
    │     │       ├── __init__.cpython-35.pyc
    │     │       └── models.cpython-35.pyc
    │     ├── tests.py
    │     └── views.py
    ├── db.sqlite3
    ├── fbckf
    │     ├── __init__.py
    │     ├── __pycache__
    │     │       ├── __init__.cpython-35.pyc
    │     │       ├── settings.cpython-35.pyc
    │     │       └── urls.cpython-35.pyc
    │     ├── settings.py
    │     ├── urls.py
    │     └── wsgi.py
    └── manage.py

  • 在項(xiàng)目主目錄中生成了一個新的文件db.sqlite3這就是 django 根據(jù)模型創(chuàng)建的數(shù)據(jù)庫文件愈涩,博客的數(shù)據(jù)也將存儲在里面

  • blog/migrations中的生成了0001_initial.py文件望抽,其中存放著 django 對數(shù)據(jù)庫的操作記錄,可以使用命令python manage.py sqlmigrate <應(yīng)用名稱> 0001查看履婉。

    $ python manage.py sqlmigrate blog 0001
    BEGIN;
    --
    -- Create model Article
    --
    CREATE TABLE "blog_article" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(50) NOT NULL UNIQUE, "body" text NOT NULL, "abstract" text NOT NULL, "create_time" datetime NOT NULL, "likes" integer unsigned NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED);
    --
    -- Create model Category
    --
    CREATE TABLE "blog_category" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(20) NOT NULL UNIQUE, "instructions" text NOT NULL);
    --
    -- Add field category to article
    --
    ALTER TABLE "blog_article" RENAME TO "blog_article__old";
    CREATE TABLE "blog_article" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "title" varchar(50) NOT NULL UNIQUE, "body" text NOT NULL, "abstract" text NOT NULL, "create_time" datetime NOT NULL, "likes" integer unsigned NOT NULL, "author_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "category_id" integer NOT NULL REFERENCES "blog_category" ("id") DEFERRABLE INITIALLY DEFERRED);
    INSERT INTO "blog_article" ("author_id", "body", "id", "create_time", "likes", "abstract", "category_id", "title") SELECT "author_id", "body", "id", "create_time", "likes", "abstract", NULL, "title" FROM "blog_article__old";
    DROP TABLE "blog_article__old";
    CREATE INDEX "blog_article_author_id_905add38" ON "blog_article" ("author_id");
    CREATE INDEX "blog_article_category_id_7e38f15e" ON "blog_article" ("category_id");
    COMMIT;

可以在輸出中看到詳細(xì)的 SQL語句

數(shù)據(jù)庫操作

?django提供了一個 shell煤篙,可以通過它來進(jìn)行數(shù)據(jù)庫的簡單操作

$ python manage.py shell
Python 3.5.2 (default, Sep 14 2017, 22:51:06) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from blog.models import Category, Article
>>> c = Category(name="古詩", instructions="古詩,是中國古代詩歌的一種體裁毁腿,又稱古體詩或古風(fēng)辑奈,指的是產(chǎn)生于唐代以前并和唐代新出現(xiàn)的近體詩(又名今體詩)相對的一種詩歌體裁")
>>> c.save()
>>> c
<Category: Category object (1)>
>>> c.name
'古詩'
>>> c.instructions
'古詩,是中國古代詩歌的一種體裁已烤,又稱古體詩或古風(fēng)鸠窗,指的是產(chǎn)生于唐代以前并和唐代新出現(xiàn)的近體詩(又名今體詩)相對的一種詩歌體裁'
>>> 
  • blog應(yīng)用的models.py中導(dǎo)入Category類,之后通過實(shí)例化一個對象胯究,并調(diào)用save()方法保存稍计,這樣就已經(jīng)在數(shù)據(jù)庫中插入了一條數(shù)據(jù)

  • save()方法繼承自models.Model

  • 實(shí)例化后 django 返回的是<Category: Category object (1)>這樣不利于觀察代碼的執(zhí)行情況,在每一個models.py的類中寫一個__str__用以返回對象的name屬性

class Category(models.Model):
    ...
    def __str__(self):
        return self.name
$ python manage.py shell
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from blog.models import Category
>>> Category.objects.all()
<QuerySet [<Category: 古詩>]>
>>> c = Category.objects.get(name='古詩')
>>> c
<Category: 古詩>
>>> 

因?yàn)槲恼骂愋枰P(guān)聯(lián)一個User對象裕循,所以這里直接使用命令創(chuàng)建一個超級用戶臣嚣,也方便接下來的管理

$ python manage.py createsuperuser
Username (leave blank to use 'csx'): fbckf
Email address: m15220982078@163.com
Password: 
Password (again): 
Superuser created successfully.
  • leave blank to use 'csx'是 django 檢測到當(dāng)前操作系統(tǒng)用戶名稱為 'csx' ,提示默認(rèn)使用 'csx' 作為超級用戶名稱

  • 之后郵箱和密碼剥哑,密碼的強(qiáng)度比較嚴(yán)格硅则,所以要好好記住自己設(shè)置的密碼

$ python manage.py shell
>>> from django.utils import timezone
>>> from django.contrib.auth.models import User
>>> from blog.models import Category, Article
>>> auth = User.objects.get(username='fbckf')
>>> c = Category.objects.get(name='古詩')
>>> article = Article(title='白云謠', author=auth, category=c, body='白云在天,丘陵自出株婴。道里悠遠(yuǎn)怎虫, 山川間之。將子無死困介,尚復(fù)能來揪垄。', abstract='白云在天,丘陵自出逻翁。', create_time=timezone.now(), likes=0)
>>> article.save()
>>> article.title
'白云謠'
>>> article.author
<User: fbckf>
>>> article.body
'白云在天饥努,丘陵自出。道里悠遠(yuǎn)八回,山川間之酷愧。將子無死,尚復(fù)能來缠诅。'
>>> 
  • 調(diào)用 django 內(nèi)置模塊timezonenow()方法指定時間

  • 使用get()方法溶浴,指定取出用戶 'fbckf' 和類別 '古詩'

  • 實(shí)例化一個 article 對象并保存

  • delete()方法用于刪除數(shù)據(jù)

總結(jié)

? 簡單來說,整一個博客應(yīng)用的編寫就是圍繞著對數(shù)據(jù)的操作進(jìn)行的管引,數(shù)據(jù)的重要性不言而喻士败。也因此,數(shù)據(jù)庫的操作也顯的尤為重要,而 django 將SQL語句都封裝起來谅将,就使得可以通過編寫 python 代碼來進(jìn)行數(shù)據(jù)庫操作漾狼,這就意味著即使不懂 SQL語句 也可以使用數(shù)據(jù)庫,極大的降低了 django 的使用門檻(當(dāng)然 SQL語句 也是很重的)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末饥臂,一起剝皮案震驚了整個濱河市逊躁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌隅熙,老刑警劉巖稽煤,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異囚戚,居然都是意外死亡酵熙,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門驰坊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绿店,“玉大人,你說我怎么就攤上這事庐橙〖傥穑” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵态鳖,是天一觀的道長转培。 經(jīng)常有香客問我,道長浆竭,這世上最難降的妖魔是什么浸须? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮邦泄,結(jié)果婚禮上删窒,老公的妹妹穿的比我還像新娘。我一直安慰自己顺囊,他們只是感情好肌索,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著特碳,像睡著了一般诚亚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上午乓,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天站宗,我揣著相機(jī)與錄音,去河邊找鬼益愈。 笑死梢灭,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播敏释,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼库快,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了颂暇?” 一聲冷哼從身側(cè)響起缺谴,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤但惶,失蹤者是張志新(化名)和其女友劉穎耳鸯,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膀曾,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡县爬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了添谊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片财喳。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖斩狱,靈堂內(nèi)的尸體忽然破棺而出耳高,到底是詐尸還是另有隱情,我是刑警寧澤所踊,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布泌枪,位于F島的核電站,受9級特大地震影響秕岛,放射性物質(zhì)發(fā)生泄漏碌燕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一继薛、第九天 我趴在偏房一處隱蔽的房頂上張望修壕。 院中可真熱鬧,春花似錦遏考、人聲如沸慈鸠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽林束。三九已至,卻和暖如春稽亏,著一層夾襖步出監(jiān)牢的瞬間壶冒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工截歉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留胖腾,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像咸作,于是被迫代替她去往敵國和親锨阿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容