上一講完成了基本博客的配置和項目工程的生成。這次開始將博客一些基本的操作主要是數據庫方面學習。
1.設計博客數據庫表結構
博客最主要的功能就是展示我們寫的文章,它需要從某個地方獲取博客文章數據才能把文章展示出來,通常來說這個地方就是數據庫。我們把寫好的文章永久地保存在數據庫里,當用戶訪問我們的博客時,Django 就去數據庫里把這些數據取出來展現給用戶。
博客的文章應該含有標題、正文、作者、發表時間等數據。一個更加現代化的博客文章還希望它有分類、標簽、評論等。為了更好地存儲這些數據,我們需要合理地組織數據庫的表結構。
我們的博客初級版本主要包含博客文章,文章會有分類以及標簽。一篇文章只能有一個分類,但可以打上很多標簽。
文章 id 標題 正文 發表時間 分類 標簽
1 title 1 text 1 2016-12-23 Django Django 學習
2 title 2 text 2 2016-12-24 Django Django 學習
3 title 3 text 3 2016-12-26 Python Python 學習
其中文章 ID 是一個數字,唯一對應著一篇文章。當然還可以有更多的列以存儲更多相關數據,這只是一個最基本的示例。
數據庫表設計成這樣其實已經可以了,但是稍微分析一下我們就會發現一個問題,這 3 篇文章的分類和標簽都是相同的,這會產生很多重復數據,當數據量很大時就浪費了存儲空間。
不同的文章可能它們對應的分類或者標簽是相同的,所以我們把分類和標簽提取出來,做成單獨的數據庫表,再把文章和分類、標簽關聯起來。下面分別是分類和標簽的數據庫表:
分類 id 分類名
1 Django
2 Python
標簽 id 標簽名
1 Django 學習
2 Python 學習
接下來就是編寫我們的數據庫模型:
以上是自然語言描述的表格,數據庫也和編程語言一樣,有它自己的一套規定的語法來生成上述的表結構,這樣我們才能把數據存進去。一般來說這時候我們應該先去學習數據庫創建表格的語法,再回來寫我們的 Django 博客代碼了。但是 Django 告訴我們不用這么麻煩,它已經幫我們做了一些事情。Django 把那一套數據庫的語法轉換成了 Python 的語法形式,我們只要寫 Python 代碼就可以了,Django 會把 Python 代碼翻譯成對應的數據庫操作語言。用更加專業一點的說法,就是 Django 為我們提供了一套 ORM(Object Relational Mapping)系統。
例如我們的分類數據庫表,Django 只要求我們這樣寫:
blog/models.pyfrom django.db import modelsclass Category(models.Model): name = models.CharField(max_length=100)
給出完整的代碼:
from django.db import modelsfrom django.contrib.auth.models import Userfrom django.utils.six import python_2_unicode_compatible# python_2_unicode_compatible 裝飾器用于兼容 Python2@python_2_unicode_compatibleclass Category(models.Model): """ Django 要求模型必須繼承 models.Model 類。 Category 只需要一個簡單的分類名 name 就可以了。 CharField 指定了分類名 name 的數據類型,CharField 是字符型, CharField 的 max_length 參數指定其最大長度,超過這個長度的分類名就不能被存入數據庫。 當然 Django 還為我們提供了多種其它的數據類型,如日期時間類型 DateTimeField、整數類型 IntegerField 等等。 Django 內置的全部類型可查看文檔: https://docs.djangoproject.com/en/1.10/ref/models/fields/#field-types """ name = models.CharField(max_length=100) def __str__(self): return self.name@python_2_unicode_compatibleclass Tag(models.Model): """ 標簽 Tag 也比較簡單,和 Category 一樣。 再次強調一定要繼承 models.Model 類! """ name = models.CharField(max_length=100) def __str__(self): return self.name@python_2_unicode_compatibleclass Post(models.Model): """ 文章的數據庫表稍微復雜一點,主要是涉及的字段更多。 """ # 文章標題 title = models.CharField(max_length=70) # 文章正文,我們使用了 TextField。 # 存儲比較短的字符串可以使用 CharField,但對于文章的正文來說可能會是一大段文本,因此使用 TextField 來存儲大段文本。 body = models.TextField() # 這兩個列分別表示文章的創建時間和最后一次修改時間,存儲時間的字段用 DateTimeField 類型。 created_time = models.DateTimeField() modified_time = models.DateTimeField() # 文章摘要,可以沒有文章摘要,但默認情況下 CharField 要求我們必須存入數據,否則就會報錯。 # 指定 CharField 的 blank=True 參數值后就可以允許空值了。 excerpt = models.CharField(max_length=200, blank=True) # 這是分類與標簽,分類與標簽的模型我們已經定義在上面。 # 我們在這里把文章對應的數據庫表和分類、標簽對應的數據庫表關聯了起來,但是關聯形式稍微有點不同。 # 我們規定一篇文章只能對應一個分類,但是一個分類下可以有多篇文章,所以我們使用的是 ForeignKey,即一對多的關聯關系。 # 而對于標簽來說,一篇文章可以有多個標簽,同一個標簽下也可能有多篇文章,所以我們使用 ManyToManyField,表明這是多對多的關聯關系。 # 同時我們規定文章可以沒有標簽,因此為標簽 tags 指定了 blank=True。 # 如果你對 ForeignKey、ManyToManyField 不了解,請看教程中的解釋,亦可參考官方文檔: # https://docs.djangoproject.com/en/1.10/topics/db/models/#relationships category = models.ForeignKey(Category) tags = models.ManyToManyField(Tag, blank=True) # 文章作者,這里 User 是從 django.contrib.auth.models 導入的。 # django.contrib.auth 是 Django 內置的應用,專門用于處理網站用戶的注冊、登錄等流程,User 是 Django 為我們已經寫好的用戶模型。 # 這里我們通過 ForeignKey 把文章和 User 關聯了起來。 # 因為我們規定一篇文章只能有一個作者,而一個作者可能會寫多篇文章,因此這是一對多的關聯關系,和 Category 類似。 author = models.ForeignKey(User) def __str__(self): return self.title
新聞熱點
疑難解答