範例:投票主題

我們建立一個簡單的線上投票網站當成範例。

建立專案與應用程式

  1. 在終端機中下達指令建立一個新的專案

    django-admin.py startproject poll
  2. poll 專案下建立一個應用程式 default

    cd poll python manage.py startapp default

調整專案設定值

修改 poll/poll/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', ]

另外,同一個檔案 poll/poll/settings.py 底下還有部份要修改的設定值,修改第 107, 109 行

# Internationalization # https://docs.djangoproject.com/en/2.0/topics/i18n/ LANGUAGE_CODE = 'zh-hant' # 將訊息的語系改為正體中文 TIME_ZONE = 'Asia/Taipei' # 以臺北時區來處理時間資料

建立資料模型

修改 poll/default/models.py,加入第 5-9 行來新增投票主題(Poll)的資料模型。在 Django 中我們可以透過資料模型與資料庫進行溝通,就不用自行撰寫 SQL 命令來操作資料:

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)

:bulb: Django 常用的資料欄位類型

欄位類型 內容 額外參數設定
CharField 文字欄位 max_length: 儲存文字個數上限
DateField 日期欄位 僅包含日期資料,不含時間
auto_now: 若設定為 True 則每次儲存時會自動將內容更新為當下日期
auto_now_add: 若設定為 True 則在第一次儲存時會自動填入當下日期
DateTimeField 日期時間欄位 額外參數同 DateField 欄位,但額外包含時間資訊
EmailField 電子郵件欄位 max_length 的設定同 CharField 類型
在資料儲存時會自動驗證內容是否符合電子郵件地址
的格式
TextField 長文字欄位 max_length 的設定同 CharField 類型
FileField 檔案欄位 upload_to: 檔案上傳後的存放路徑
ImageField 圖片欄位 同 FileField。
width_fieldheight_field 當每次上傳圖檔後,系統會自動將圖片的寬與高填入
這兩個屬性,以便日後查詢

更多欄位類別及詳情請參見:
https://docs.djangoproject.com/en/2.0/ref/models/fields/#field-types

執行以下指令建立資料庫與管理員帳號:

python manage.py makemigrations python manage.py migrate python manage.py createsuperuser

連結網站管理頁面

開啟網站服務

python manage.py runserver 0.0.0.0:80

請在瀏覽器中的網址列輸入 http://localhost/admin/ 來存取 Django 內建的管理後臺。

輸入超級管理員的帳號密碼後,登入網站管理後臺

將自訂資料模型也納入內建管理後臺

修改 poll/default/admin.py,新增第 2, 5 行

from django.contrib import admin from .models import * ## Register your models here. admin.site.register(Poll)

修改完成後重新載入管理介面,應該會看到上面出現 Poll 的管理界面,我們可以在這個管理後台做新增、讀取、編輯、刪除的動作了。

點選 Polls 後面的「新增」連結來隨意建立 2 個投票主題(Poll),例如:

新增投票主題後會自動轉至投票主題列表的畫面,這時出現的文字是 Poll Object ,如果我們希望出現有意義的內容,須在 model.py 中加入程式碼 第 11-12 行

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

視圖、網址、範本

使用者透過瀏覽器存取 Django 專案網站服務時,大致流程如下圖:

我們要建立第一個網頁,開啟 poll/poll/urls.py ,修改為以下程式碼:

from django.contrib import admin from django.urls import path, include urlpatterns = [ path('admin/', admin.site.urls), path('', include('default.urls')), ]

投票主題列表

網址

新增檔案 poll/default/urls.py ,定義應用程式 default 的路徑規則。

from django.urls import path from . import views urlpatterns = [ path('poll/', views.PollList.as_view()), ]

視圖

開啟 poll/default/views.py ,新增第 2 - 8 行

from django.shortcuts import render from django.views.generic import ListView from .models import * # Create your views here. # 投票主題列表 class PollList(ListView): model = Poll

範本

  1. 建立頁面範本資料夾 poll/default/templates/default

  2. 為了維持整個網站頁面間外觀的一致性,先新增網站頁面範本檔案 poll/default/templates/base.html

    <!DOCTYPE html> <html lang="zh-hant"> <head> </head> <body> <div id="main-content"> {% block content %}{% endblock %} </div> </body> </html>
  3. 新增投票主題列表頁面範本 poll/default/templates/default/poll_list.html

    {% extends "base.html" %} {% block content %} <h1>投票主題</h1> <ul> {% for poll in poll_list %} <li>{{ poll.date_created }} <a href="{{ poll.id }}/">{{ poll.subject }}</a></li> {% endfor %} </ul> {% endblock %}

啟動網站,在網址列輸入 http://localhost/poll/ 會出現以下頁面:

使用者表單

在前面的章節中使用的 Django 內建的後臺管理界面對自訂的資料模型 Poll 進行操作。但後臺管理界面較偏向一般化的操作,可能無法滿足我們對操作流程的要求,此時可以透過使用者表單在頁面上收集使用者的輸入值,藉此對資料模型所對應的資料表進行新增、刪除、修改等操作。

投票主題

由於這個範例的資料比較單純,我們可以透過 Django 的通用編輯視圖(Generic editing views)類別來進行資料的「增(Create)」、「刪(Delete)」、「修(Update)」的動作。

修改資料模型

開啟 poll/default/models.py,修改 Poll 資料模型:

class Poll(models.Model): # 投票主題文字,至多 200 字 subject = models.CharField(max_length=200, verbose_name='主題') # 投票建立日期,在建立時若未指定,則自動填入建立時的時間 date_created = models.DateField(auto_now_add=True) def __str__(self): return str(self.id) + ")" + self.subject

新增資料(Create)

路徑

修改 poll/default/urls.py,增加路徑規則。新增第 6 行

from django.urls import path from . import views urlpatterns = [ path('poll/', views.PollList.as_view()), path('poll/create/', views.PollCreate.as_view()), ]
視圖

開啟 poll/default/views.py,增加以下程式碼:

from django.views.generic.edit import CreateView, UpdateView, DeleteView
# 新增投票主題 class PollCreate(CreateView): model = Poll fields = ['subject'] # 指定要顯示的欄位 success_url = '/poll/' # 成功新增後要導向的路徑 template_name = 'form.html' # 要使用的頁面範本
範本

新增通用表單範本檔案 poll/default/templates/form.html

{% extends "base.html" %} {% block content %} <form action="" method="post"> {% csrf_token %} <table> {{ form.as_table }} </table> <input type="submit" value="送出"> </form> {% endblock %}

更新投票主題列表範本

開啟 poll/default/templates/default/poll_list.html,修改為以下程式碼。

{% extends "base.html" %} {% block content %} <h1>投票主題</h1> <a href="/poll/create/">新增投票主題</a> <ul> {% for poll in poll_list %} <li> {{ poll.date_created }} <a href="/poll/{{ poll.id }}/">{{ poll.subject }}</a> </li> {% endfor %} </ul> {% endblock %}

修改資料(Update)

網址

開啟 poll/default/urls.py,增加第 7 行的路徑規則:

from django.urls import path from . import views urlpatterns = [ path('poll/', views.PollList.as_view()), path('poll/create/', views.PollCreate.as_view()), path('poll/<int:pk>/update/', views.PollUpdate.as_view()), ]
視圖

開啟 poll/default/views.py,增加以下程式碼:

# 修改投票主題 class PollUpdate(UpdateView): model = Poll fields = ['subject'] # 指定要顯示的欄位 success_url = '/poll/' # 成功新增後要導向的路徑 template_name = 'form.html' # 要使用的頁面範本
範本

與新增投票主題共用頁面範本 form.html,不另行設置。

刪除資料(Delete)

網址

開啟 poll/default/urls.py,新增第 8 行路徑規則:

from django.urls import path from . import views urlpatterns = [ path('poll/', views.PollList.as_view()), path('poll/create/', views.PollCreate.as_view()), path('poll/<int:pk>/update/', views.PollUpdate.as_view()), path('poll/<int:pk>/delete/', views.PollDelete.as_view()), ]
視圖

開啟 poll/default/views.py,增加以下程式碼:

# 刪除投票主題 class PollDelete(DeleteView): model = Poll success_url = '/poll/' template_name = "confirm_delete.html"
範本

新增確認刪除頁面範本檔案 poll/default/templates/confirm_delete.html

{% extends "base.html" %} {% block content %} <h1>刪除紀錄</h1> <form action="" method="post"> <p>確定要刪除 {{ object }} 這筆紀錄嗎?</p> {% csrf_token %} <input type="submit" value="是的,我要刪除"> </form> {% endblock %}

更新投票主題列表範本

開啟 poll/default/templates/default/poll_list.html,修改為以下程式碼:

{% extends "base.html" %} {% block content %} <h1>投票主題</h1> <a href="/poll/create/">新增投票主題</a> <ul> {% for poll in poll_list %} <li> {{ poll.date_created }} <a href="/poll/{{ poll.id }}/">{{ poll.subject }}</a> | <a href="/poll/{{ poll.id }}/update/">修改</a> | <a href="/poll/{{ poll.id }}/delete/">刪除</a> </li> {% endfor %} </ul> {% endblock %}

主要修改項目如下: