網站程式與資料庫語法簡介-ok
-
<style> .markdown-body img:not(.emoji) { border-radius: 5px; box-shadow: 1px 1px 5px dimgrey; } </style>
【範例】線上投票-與資料庫互動
在這個範例中,我們建立一個簡單的線上投票網站來示範如何與資料庫互動。
在終端機中按下 Ctrl + C 中斷程式執行,回到命令提示模式。
建立專案與應用程式
(1)在終端機中下達指令建立一個新的專案django-admin startproject poll109
- `django-admin.py` 是安裝 Django 後提供的管理工具
- `startproject` 的意思是在目前的工作資料夾下新建一個 Django 專案,現在要建立的投票網站就可算是一個專案
- `poll109` 是要建立的專案名稱,可以自行命名。因為要建立投票網站,所以在這邊以 `poll109` 當成專案的名稱。
打完指令後,會產生一個 `poll` 的資料夾poll109/ manage.py poll109/ __init__.py settings.py urls.py wsgi.py
(2)建立一個應用程式cd poll109 python manage.py startapp default
- ++第 1 行++,將工作資料夾切換到方才建立的 poll109 專案
- ++第 2 行++,透過專案資料夾中的 `manage.py` 腳本建立應用程式
- `python` 是用來解譯腳本的程式
- `manage.py` 是被解譯執行的腳本程式,這支程式在建立 Django 專案的時候會被自動放在專案資料夾內,它被用來協助使用者管理 Django 專案,之後會常常需要它
- `startapp` 是 `manage.py` 所提供/接受的參數,用來指示 `manage.py` 腳本幫忙在專案內新增應用程式
- `default` 是欲新增的應用程式名稱,可自行命名。若要建立的網站功能較為複雜,通常會將其分割成多個應用程式,每個應用程式就專注處理它所對應的功能,例如:教學網站可能可以切分為身分認證、學生功能、教師功能...等的應用程式。一個專案內可包含多個應用程式。
調整專案設定值
修改 `poll109/settings.py`ALLOWED_HOSTS = ['*'] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'default', ]
- ++第 28 行++,將 `ALLOWED_HOSTS` 的內容改為 `['*']`,它是用來限制用戶端可以使用哪些主機名稱來存取這個專案。
- 若將專案放在 `poll.example.org` 主機上讓用戶端存取的話,這樣用戶端就會透過 `poll.example.org` 作為主機名稱來存取專案網站的服務,這樣的話,就需要將其加入 `ALLOWED_HOSTS` 中,例:
`ALLOWED_HOSTS = ['poll.example.org']`
- 若用戶端以 `ALLOWED_HOSTS` 列表以外的主機名稱嚐試要存取網站服務,會遭到 Django 拒絕,例:
- `ALLOWED_HOSTS` 預設值是空的,表示只接受來以本機(localhost, 127.0.0.1)為主機名稱的存取
- 將 `ALLOWED_HOSTS` 列表設為 `['*']` 表示接受所有主機名稱,這個在網站發展的階段可以這樣設定以方便測試,若網站實際上線提供服務後,建議還是指定只能以特定主機名稱存取較為安全
- 新增++第 40 行++,將方才自行建立的應用程式 `default` 也加入網站專案
另外,同一個檔案 `poll/settings.py` 底下還有部份要修改的設定值:# Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ LANGUAGE_CODE = 'zh-hant' TIME_ZONE = 'Asia/Taipei'
- 修改++第 107 行++,將 `LANGUAGE_CODE` 的值由預設的 `en-us` 改為 `zh-hant`,表示想使用正體中文語系的訊息
上圖:預設英語版(en-us)的管理後臺登入畫面。
下圖:正體中文版(zh-hant)的管理後臺登入畫面。- 修改++第 109 行++,將 `TIME_ZONE` 的值設由 `UTC` 改為 `Asia/Taipei`,表示想用臺北所在時區來處理時間資料
建立資料模型
修改 `default/models.py`
from django.db import models # Create your models here. class Poll(models.Model): # 投票主題文字,至多 200 字 subject = models.CharField('投票主題', max_length=200) # 投票建立日期,在建立時若未指定,則自動填入建立時的時間 date_created = models.DateField('建立時間', auto_now_add=True) class Option(models.Model): # 此選項屬於哪一個投票 poll_id = models.IntegerField('所屬投票主題') # 選項文字 title = models.CharField('選項文字', max_length=200) # 此選項被投票數 count = models.IntegerField('已投票數', default=0)
- 加入++第 5-17 行++,新增投票主題(`Poll`)以及投票選項(`Option`)的資料模型,在 Django 中透過資料模型與資料庫進行溝通,可以不用自行撰寫 SQL 命令來操作資料。
- `Poll` 與 `Option` 皆是繼承自 Django 內建的 `models.Model` 類別(class)
- `Poll` 投票主題有 2 個欄位
- `subject` 欄位為單行文字(`models.CharField`),至多 200 個字元(`max_length=200`)
- `date_created` 欄位為日期欄位(`models.DateField`),用來記錄此投票被建立的日期,後方的 `auto_now_add=True` 的意思是,在建立一筆投票主題記錄時,自動將這個欄位的值設為建立時的日期
- `Option` 投票選項有 3 個欄位
- `poll_id` 欄位為整數(`models.IntegerField`),用來記錄此選項屬於哪一個投票主題
- `title` 為單行文字,用來儲存此選項的文字
- `count` 亦為整數欄位,用來記錄這個選項被投了幾次,預設值為 `0`
:::info
:bulb: **Django 常用的資料欄位類型**
|欄位類型|內容|額外參數設定|
|-|-|-|
|CharField|文字欄位|***max_length***: 儲存文字個數上限|
|DateField|日期欄位|僅包含日期資料,不含時間<br>***auto_now***: 若設定為 `True` 則每次儲存時會自動將內容更新為當下日期<br/>***auto_now_add***: 若設定為 `True` 則在第一次儲存時會自動填入當下日期|
|DateTimeField|日期時間欄位|額外參數同 DateField 欄位,但額外包含時間資訊|
|EmailField|電子郵件欄位|***max_length*** 的設定同 CharField 類型<br>在資料儲存時會自動驗證內容是否符合電子郵件地址<br>的格式|
|TextField|長文字欄位|***max_length*** 的設定同 CharField 類型|
|FileField|檔案欄位|***upload_to***: 檔案上傳後的存放路徑|
|ImageField|圖片欄位|同 FileField。<br>***width_field*** 與 ***height_field*** 當每次上傳圖檔後,系統會自動將圖片的寬與高填入<br>這兩個屬性,以便日後查詢
更多欄位類別及詳情請參見:
https://docs.djangoproject.com/en/5.0/ref/models/fields/#field-types
:::
執行以下指令建立資料庫python manage.py makemigrations python manage.py migrate python manage.py createsuperuser
- ++第 1 行++,依照資料表定義的內容產生資料庫異動腳本
- ++第 2 行++,將資料庫異動腳本實際套用在資料庫上
==以上 2 個指令在每次對資料表定義做過更動後,都需要執行一次,才會生效。==
- ++第 3 行++,建立超級使用者帳號,這個帳號在 Django 框架內預設擁有最高權限,可將其想成是網站管理員。建立超級使用者只需要在專案一開始時做一次就好了。
連結網站管理頁面
開啟網站服務
python manage.py runserver 0.0.0.0:80
請在瀏覽器中輸入以下網址,以後入 Django 內建的管理後臺
http://localhost/admin
輸入超級管理員的帳號密碼後,登入網站管理後臺
將自訂資料模型納入管理後臺修改 `poll109/default/admin.py`
from django.contrib import admin from .models import * ## Register your models here. admin.site.register(Poll) admin.site.register(Option)
- 新增++第 2 行++,表示要由現行應用程式(`.` 也就是 `default`)的 `models.py` 引用其所有項目
- 新增++第 5-6 行++,向 `admin` 模組註冊 `Poll` 與 `Option` 這 2 個資料模型,這樣就可以利用內建的 `admin` 管理模組來管理 `Poll` 與 `Option` 這 2 個資料模型所對應的資料庫的內容
修改完成後重新載入管理介面,應該會看到上面出現 `Poll` 跟 `Option` 的管理界面,我們可以在這個管理後台做新增、讀取、編輯、刪除的動作了。
點選 `Polls` 後面的「新增」連結來建立 2 個投票主題(Poll):
* 趕快來投票決定班遊地點!!!
* 同樂會最想吃什麼?
新增投票主題後會自動轉至投票主題列表的畫面,這時出現的文字是 `Poll Object(數字)` ,如果我們希望出現有意義的內容,須在 `model.py` 中加入程式碼 ++第11-12, 22-23行++:from django.db import models # Create your models here. class Poll(models.Model): # 投票主題文字,至多 200 字 subject = models.CharField('投票主題', max_length=200) # 投票建立日期,在建立時若未指定,則自動填入建立時的時間 date_created = models.DateField('建立時間', auto_now_add=True) def __str__(self): return str(self.id) + ")" + self.subject class Option(models.Model): # 此選項屬於哪一個投票 poll_id = models.IntegerField('所屬投票主題') # 選項文字 title = models.CharField('選項文字', max_length=200) # 此選項被投票數 count = models.IntegerField('已投票數', default=0) def __str__(self): return str(self.poll_id) + ": " + self.title
- Django 內建的 `admin` 管理模組會透過 `models.Model` 類別下的 `__str__()` 方法(method)將資料表的記錄轉成代表字串,因此我們在 `Poll` 與 `Option` 這 2 個自訂的類別下分別定義 `__str__` 這個方法,回傳記錄的代表字串。
- 在這個範例中,我們以 `id` 欄位和 `subject` 欄位的內容當成 `Poll` 類別的代表字串,以 `poll_id` 欄位和 `title` 欄位的內容做為 `Option` 類別的代表字串。
- 如果沒有另外指定的話,Django 會自動在資料表中加入 1 個名為 `id` 的隱藏用來做為每筆紀錄的鍵值(識別代碼)
接著為投票主題「趕快來投票決定班遊地點!!!」,新增投票選項,記得要指定「所屬投票主題」的值為 `1` (因為該投票主題的 `id` 值為 `1`)
* 淡水老街吃吃喝喝養豬行程
* 大稻埕文化巡訪文青行程
* 陽明山賞花趣拈花惹草行程