在django開發中,一般我們初始化一個項目之后,創建應用一般就會生成如下的目錄:
django-admin startproject myproject
python manage.py startapp blog
myproject/
├── manage.py
└── myproject/
| ├── __init__.py
| ├── settings.py
| ├── urls.py
| └── wsgi.py
|___blog|___models.py|___......
其中model.py就是定義數據庫表的文件。文件中的每個類就是就對應的數據庫中的每張表。
比如models.py里面有如下一個類和對應的數據庫中的關系如下所示:
from django.db import modelsclass BlogPost(models.Model):"""博客文章模型類數據庫中對應的表名為: blog_post (Django 自動將類名轉換為小寫并用下劃線連接)"""title = models.CharField(max_length=200, verbose_name="文章標題")# 數據庫對應: VARCHAR(200) 字段,NOT NULL 約束content = models.TextField(verbose_name="文章內容")# 數據庫對應: TEXT 字段,NOT NULL 約束author = models.ForeignKey('auth.User',on_delete=models.CASCADE,verbose_name="作者")# 數據庫對應: 外鍵字段,關聯到 auth_user 表的 id 字段# 實際存儲為 author_id 整數列created_at = models.DateTimeField(auto_now_add=True, verbose_name="創建時間")# 數據庫對應: DATETIME 字段,NOT NULL# 僅在對象首次創建時自動設置為當前時間updated_at = models.DateTimeField(auto_now=True, verbose_name="更新時間")# 數據庫對應: DATETIME 字段,NOT NULL# 每次保存對象時自動更新為當前時間is_published = models.BooleanField(default=False, verbose_name="是否發布")# 數據庫對應: BOOLEAN/TINYINT(1) 字段,默認值為 0 (False)class Meta:verbose_name = "博客文章"verbose_name_plural = "博客文章"ordering = ['-created_at']# 數據庫對應: 表將按 created_at 降序排列
執行
python manage.py makemigrations python migrate
這里執行makemigrations的作用就在在對應的app目錄下面生成migrations目錄,里面會有一些python文件,記錄了對model.py的修改。相當于git可以對models.py的每次修改做checkpoint。 舉個例子。比如我在models.py里面第一次創建了數據庫類,執行了makemigrations命令,這樣就會在對應的migrations目錄下面生成一個pyhton文件,編號從0001_.......py開始記錄這一次的改動。后來我又修改了model.py里面的一些字段的命名。執行了makemigrations命令,這樣就又會生成第二個0002_.......py文件。里面保存了這次對于這些字段修改的checkpoint。同時在django中,這個下面生成的文件名是易讀的,可以從文件名大概知道改動的內容。
第二個執行完makemigrations命令之后,執行migrate就是把生成的哪些編號從0001開始的哪些文件的改動,同步到數據庫中,該建表的建表。該修改字段的修改字段等等。這一步就是對數據庫真正產生影響的步驟。
所以這里在做數據庫遷移的時候,如果遇到遷移失敗,我們是其實可以像git一樣,回退遷移文件到最開始的時候也就是__inti__.py的時候,然后直接重新生成遷移文件,在做遷移
比如上面的代碼執行之后,最后會在數據庫中創建以下結構的表:
1.表名:blog_post2.字段:id (自動創建的主鍵,INTEGER PRIMARY KEY AUTOINCREMENT)title (VARCHAR(200) NOT NULL)content (TEXT NOT NULL)author_id (INTEGER NOT NULL, 外鍵關聯到 auth_user 表)created_at (DATETIME NOT NULL)updated_at (DATETIME NOT NULL)is_published (BOOLEAN/TINYINT(1) NOT NULL, 默認 0)3.外鍵約束:FOREIGN KEY(author_id) REFERENCES auth_user(id) ON DELETE CASCADE