Photo by Radu Marcusu on Unsplash
在經營網站的過程中,通常都會有存取資料的動作,像是撈取使用者所查詢的資料、儲存表單內容及修改帳號資訊等,是一個不可或缺的功能,而本文將分享Django框架如何透過ORM(Object Relational Mapping)的技術,實現利用物件的概念,操作資料庫,提升開發的靈活性及降低Django專案與資料庫的相依性。
接續建立Django應用程式(APP)文章,完成應用程式(APP)的新增後,接下來,本文將利用Django的Migration(資料遷移),來建立資料庫。重點包含:
接續建立Django應用程式(APP)文章,完成應用程式(APP)的新增後,接下來,本文將利用Django的Migration(資料遷移),來建立資料庫。重點包含:
- Django Model(資料模型)
- 註冊Django應用程式(APP)
- Django Migration(資料遷移)
- SQLite資料庫
一、Django Model(資料模型)
Django框架中的Model(資料模型),其實就是利用ORM(Object Relational Mapping)的程式設計技術,將資料庫、資料表及欄位等,抽象化為程式設計中的類別(Class)和屬性(Attribute),除了降低Django專案對於資料庫的相依性外,在開發的過程中,也能夠輕鬆的利用物件來操作資料。
而Django應用程式(APP)中的models.py,即是利用此概念,在其中定義類別名稱(Class)及屬性(Attribute),接著透過Django的Migrate(遷移)技術,在資料庫中建立相應的資料表及欄位。
舉例來說,Django專案中的posts應用程式(APP),想要在資料庫中建立「景點位置」及「景點貼文」資料表,並且是一對多的關係(例如:中壢景點位置,可能有一到多個的景點貼文。這時候則可以在models.py中設計如下的類別(Class):
而Django應用程式(APP)中的models.py,即是利用此概念,在其中定義類別名稱(Class)及屬性(Attribute),接著透過Django的Migrate(遷移)技術,在資料庫中建立相應的資料表及欄位。
舉例來說,Django專案中的posts應用程式(APP),想要在資料庫中建立「景點位置」及「景點貼文」資料表,並且是一對多的關係(例如:中壢景點位置,可能有一到多個的景點貼文。這時候則可以在models.py中設計如下的類別(Class):
from django.db import models
from django.utils import timezone
# 景點位置
class Location(models.Model):
name = models.CharField(max_length=255) #位置名稱
#景點貼文
class Post(models.Model):
subject = models.CharField(max_length=255) #標題
content = models.CharField(max_length=255) #內容
author = models.CharField(max_length=20) #貼文者
create_date = models.DateField(default=timezone.now) #貼文時間
location = models.ForeignKey(Location, on_delete=models.CASCADE) #景點位置
首先,類別(Class)需繼承models模組中的Model類別,其中封裝了存取資料庫的所有操作,例如新增、刪除、修改、查詢資料等。
而models模組中,提供許多抽象化資料表欄位的類別,例如:
而models模組中,提供許多抽象化資料表欄位的類別,例如:
- CharField:字串欄位
- IntegerField:整數欄位
- FloatField:浮點數欄位
- DateField:日期欄位
- ImageField:圖片欄位
在類別(Class)中即可利用這些欄位類別,來建立資料庫欄位的屬性(Attribute)。其中,CharField可以透過Python關鍵字參數(Keyword Argument)來限制長度。另外,範例中的DateField(日期欄位),可以引用timezone類別,在新增景點貼文時,預設存入目前時區的時間。
最後,由於要建立「景點位置」及「景點貼文」一對多的關係,所以透過ForeignKey類別來進行設定,而on_delete=models.CASCADE的意思是,當「景點位置」資料表中的資料被刪除時,相對應的「景點貼文」資料也跟著刪除。
最後,由於要建立「景點位置」及「景點貼文」一對多的關係,所以透過ForeignKey類別來進行設定,而on_delete=models.CASCADE的意思是,當「景點位置」資料表中的資料被刪除時,相對應的「景點貼文」資料也跟著刪除。
二、註冊Django應用程式(APP)
資料模型models.py定義完成後,接下來需要將應用程式(APP)註冊至主程式potrip中,讓其知道有posts應用程式(APP)的存在。
而註冊的方式為開啟主程式potrip下的settings.py,找到INSTALLED_APPS串列(List),可以看到其中包含了Django專案中的所有應用程式(APP),接著,將posts應用程式(APP)下的apps.py設定檔中的PostsConfig類別路徑新增進去,如下範例:
而註冊的方式為開啟主程式potrip下的settings.py,找到INSTALLED_APPS串列(List),可以看到其中包含了Django專案中的所有應用程式(APP),接著,將posts應用程式(APP)下的apps.py設定檔中的PostsConfig類別路徑新增進去,如下範例:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'posts.apps.PostsConfig'
]
這樣就完成了posts應用程式(APP)註冊的動作。
三、Django Migration(資料遷移)
Migration(資料遷移)實際上是一個Python檔案,用來同步Django專案下models.py中的類別(Class)及資料庫。也就是說,只要Django專案中的models.py有任何的變動,都要執行一次Migration(資料遷移),來同步資料庫。
接下來即可透過以下的指令,建立Migration(資料遷移)檔案:
接下來即可透過以下的指令,建立Migration(資料遷移)檔案:
python manage.py makemigrations
執行結果
其中所建立的Migration(資料遷移)檔案,存放在應用程式(APP)下的migrations資料夾中。來看一下Migration(資料遷移)所產生的0001_initial.py檔案內容,如下:
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Location',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
],
),
migrations.CreateModel(
name='Post',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('subject', models.CharField(max_length=255)),
('content', models.CharField(max_length=255)),
('author', models.CharField(max_length=20)),
('create_date', models.DateField(verbose_name=django.utils.timezone.now)),
('location', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='posts.Location')),
],
),
]
可以看到,Migration(資料遷移)檔案中,定義了將要在資料庫執行的動作。而接下來所要執行的migrate指令,則會依照此Migration(資料遷移)檔案,同步models.py中所建立的類別至資料庫中:
python manage.py migrate
執行結果
從執行結果可以看到,posts應用程式(APP)的Migration(資料遷移)已成功執行。另外,如果想要知道執行Migration(資料遷移)時,背後所產生的SQL指令,則可以利用sqlmigrate指令,加上應用程式(APP)名稱及Migration(資料遷移)檔案的前方代碼,如下範例:
python manage.py sqlmigrate posts 0001
執行結果四、SQLite資料庫
SQLite是一個輕量級的資料庫,通常運用在資料量不多的應用程式上,而Django框架預設即提供了SQLite資料庫。
為了方便管理SQLite資料庫及查看剛剛執行Migration(資料遷移)的結果,可以至SQLite Browser下載管理工具,安裝完成後,會看到如下畫面:
為了方便管理SQLite資料庫及查看剛剛執行Migration(資料遷移)的結果,可以至SQLite Browser下載管理工具,安裝完成後,會看到如下畫面:
接著,回到桌面將Django專案中的db.sqlite3檔案拖拉至空白處,結果如下:
從中即可看到,Django專案所執行的posts應用程式(APP) Migration(資料遷移),成功的在資料庫中建立「景點位置」及「景點貼文」資料表。
五、小結
以上就是Django Migration(資料遷移)的基本觀念,透過這樣的技術,開發人員即可在Django專案中,靈活的切換不同的資料庫,並且利用物件的觀念來操作資料。如果在練習的過程中,有遇到任何問題,歡迎留言提問,我將會盡力為大家解答。
如果資料遷移時出現No changes detected該如何處裡
回覆刪除您好,請確認在執行資料遷移前,是否有將應用程式(APP)加入到settings.py檔案的INSTALLED_APPS中呢?一定進行加入的動作,專案主程式才會認識應用程式(APP),進而偵測到資料模型有變動唷 :)
刪除我有加入 'posts.apps.PostsConfig' 在INSTALLED_APPS中,終端執行時還是失敗,
刪除資料遷移時出現No changes detected,請問mike 大是那裡有漏掉?
嗨 我發現 如果再INSTALLED_APPS 同時會有兩個 config 會依照下面那個判斷,如果直接加入文中的那一串 會沒辦法完成註冊,需要找到 INSTALLED_APPS 再加入那一行 'posts.apps.PostsConfig' 建議元PO 可以提醒一下
回覆刪除