Django專案
-
Django專案
- 建立專案(以 iOS 為例)
1. 開啟「終端機」程式
在電腦畫面下方的工作列找到「終端機 」圖示,點選圖示執行程式。
在「終端機 」中輸入指令「cd mydjango 」,會出現如下畫面。
在「終端機 」中輸入指令「source mydjango_venv/bin/activate 」,會出現如下畫面。
2. 建立專案
django-admin startproject mysite
- `django-admin` 是安裝完 django 開發框架後,由框架提供的一個命令列管理工具
- `startproject` 是告訴管理工具說我們想要建立一個新的專案
- `mysite` 是要建立的專案名稱,可以自行命名打完指令後,會產生一個與專案名稱同名的資料夾,此例名為 `mysite` 的資料夾,其資料夾架構大致如下:
mysite/ ├── manage.py └── mysite/ ├── asgi.py ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py
- `manage.py`
管理專案的腳本檔,接下來如果要對這個專案進行一些操作,例如:啟動專案、建立專案使用者、資料庫遷移...等,都得透過它來執行。
- 專案資料夾內會再有一個與專案同名的資料夾,以本例來說就是 `mysite`,其中包含了專案的設定與路徑規則等
- `settings.py` 專案的主要設定檔
- `urls.py` 專案的路徑規則,要來呈現當使用者以瀏覽器存取哪個路徑時,需要由哪個處理函式或類別來處理請求、做出回應- 測試執行專案
1. 建立完專案後,將工作目錄切換至方的建立的專案資料夾
cd mysite
2. 接下來我們試著將專案啟動:
python manage.py runserver 0.0.0.0:80
- `manage.py` 是建立專案時,Django自動幫我們建立此專案專屬的管理腳本
- `runserver` 我們介紹第一個命令,表示要將專案伺服器執行起來
- `0.0.0.0:80` 表示伺服器要綁定的位址及埠號若成功執行,應該會看到如下畫面:
3. 開啟瀏覽器,在網址列輸入`http://localhost/`,主機會回應 Django 網站畫面如下:
要先啟動專案(管理腳本的 `runserver` 命令),不然瀏覽器看不到東西噢!
建立應用程式
我們要建立一個圖文展示的應用程式,在命令提示字元按 <kbd>Ctrl</kbd>+<kbd>C</kbd> 中止網站服務,並重新輸入以下指令:
python manage.py startapp show
- `startapp` 這是我們學到的 `manage.py` 管理腳本的第 2 個命令,用來在專案內新增一個應用程式(App)
- `show` 欲新增的應用程式名稱,可自行需要自行命名下了這個指令後,會在專案資料夾 `mysite` 底下自動新增一個 `show` 資料夾,整個專案的檔案結構如下:
mysite/ ├── manage.py ├── mysite/ │ ├── asgi.py │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── show/ ├── admin.py ├── apps.py ├── __init__.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py
修改 `mysite/settings.py` 以註冊應用程式,新增++第 40 行++:
# Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'show', # <--- 將應用程式 show 加入專案網站 ]
要完成一個可以回應給使用者的畫面,需要有兩個步驟:
1. 設定路徑規則(`urls.py`)
2. 撰寫處理視圖(`views.py`)- 設定路徑規則
打開 `mysite/urls.py` 裡面已有的設定如下:
from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
新增++第 19, 23 行++:
from django.contrib import admin from django.urls import path from show import views # <--- 新增這行,從應用程式 show 引用它的 views 模組 urlpatterns = [ path('admin/', admin.site.urls), path('', views.homepage), # <--- 新增這行,指定路徑及其對應的處理函式 ]
- `urlpatterns` 這個清單裡每一項都是一條路徑規則,用 `path` 來定義存取路徑與處理函式的對應關係
- `path` 函式的第一個參數,表示要接受請求的路徑,第二個參數表示要將該路徑的存取要求轉介給哪一個處理函式處理
- `path('admin/', admin.site.urls)`
如果請求路徑是 `admin/` 的話,由內建的後臺管理應用程式 `admin` 處理
- `path('', views.homepage),`
如果是空路徑 `` 由 `views` 模組的 `homepage` 來處理
- 撰寫處理視圖函式(`views.py`)
打開 `show/views.py` 將其修改為以下程式碼:
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def homepage(request): return HttpResponse('歡迎光臨魏小良的網站')
在終端機輸入以下指令以執行網站服務:
python manage.py runserver 0.0.0.0:80
然後在瀏覽器的網址列中輸入 `http://localhost/` 來測試你的網站,應該會看到這行訊息:
- 使用模版(頁面範本)
1. 在 `mysite` 專案資料夾下建立模版目錄 `templates`,新增後整個專案的資料夾結構應該如下(省略 `mysite`, `show` 等子資料夾的內容):
mysite/ manage.py mysite/ show/ templates/
2. 修改 `mysite/mysite/settings.py` ++第 58 行++:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['templates'], # <--- 修改這一行 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ]
- ++第 58 行++,將 `TEMPLATES` 下的 `DIRS` 由空清單 `[]` 修改為 `['templates']`,表示要額外指定專案資料夾下的 `templates` 資料夾做為存放模版(頁面範本)的地方
3. 在模版目錄中建立網頁模版 `index.html`
<html> <head> </head> <body> 歡迎光臨我的網站 </body> </html>
4. 修改 `show/views.py`
from django.shortcuts import render # Create your views here. def homepage(request): return render(request, 'index.html')
餐廳網站
假設我們現在要做一個簡單的餐廳網站,網站首頁會顯示餐廳提供的 3 種餐點。點按餐點名稱的連結後,可以看到該餐點的圖片。
1. 建立靜態檔案目錄 `static`
2. 請將下面 3 張圖片下載並複製到 `static/` 資料夾內。
圖片 檔名 food1.png food2.png food3.png
3. 修改專案設定檔 `mysite/settings.py` 來指定靜態檔案的存放路徑。# Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.0/howto/static-files/ STATIC_URL = 'static/' STATICFILES_DIRS = [ BASE_DIR / 'static', ]
- 新增++第 121-123 行++,新增 `STATICFILES_DIRS` 這個清單來指定靜態檔案的存放路徑
- ++第 122 行++的意思是,專案所在的資料夾下的 `static` 目錄
- `BASE_DIR` 在 `settings.py` 前面有定義過,它的內容就是這個專案資料夾的路徑
- 什麼是靜態檔案?
靜態檔案指的是在網站上幾乎不會變動的內容,像是網站上使用的 Logo 圖片,參考的外部 CSS 檔案以及引用的外部 Javascript 檔,或是提供使用者下載的 Word 文件,PDF檔等等。
4. 修改專案路徑規則檔 `mysite/urls.py`from django.contrib import admin from django.urls import path, include # <--- 附加 , include from show import views urlpatterns = [ path('admin/', admin.site.urls), path('', views.homepage), path('show/', include('show.urls')), # <--- 新增此行 ]
- 修改++第 18 行++,附加引用 `include` 這項資源(函式)
- 插入++第 24 行++,這行的意思是,將應用程式 `show` 的 `urls` 所定義的路徑規則,以 `show/` 為前置路徑進行展開,並加入專案的路徑規則中。
5. 新增應用程式 `show` 的路徑規則檔 `show/urls.py`,來定義 `show` 應用程式的路徑規則:from django.urls import path from . import views urlpatterns = [ path('food/<int:kind>', views.food), ]
- 這裡只定義了一條規則,路徑 `food/<int:kind>` 的請求交由 `views.food` 來處理
- `<int:kind>` 是一種特殊表示法,表示這裡如果是整數(`int`)的話,將整數擷取出來當成 `views` 對應處理函式的參數,並將其命名為 `kind`6. 修改 `show/views.py`,變更為以下內容:
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def homepage(request): foods = ['三明治套餐', '鬆餅套餐', '漢堡套餐'] return render(request, 'index.html', {'foods':foods}) def food(request, kind): return render(request, 'food.html', {'kind':kind})
- ++第 6 行++定義了名為 `foods` 的清單
- ++第 7 行++,這邊在呼叫 `render` 函式時,提供了第 3 個為字典型態的引數,用來傳遞內容給頁面範本處理。字典的鍵值(Key)是等等在頁面範本中可以用來存取資料的變數名稱,對應值(Value)則是實際上要傳給頁面範本的資料內容。
- ++第 9 行++,處理函式的參數變成了 2 個,第 2 個參數名稱 `kind` 是前面路徑規則從路徑中擷取到的資訊:path('food/<int:kind>', views.food)
7. 新增 `mysite/show/template/index.html` ++第 5-8 行++:
<html> <head> </head> <body> 歡迎光臨我的網站<BR> {% for food in foods %} <p>{{ forloop.counter }} - <a href="/show/food/{{forloop.counter}}">{{food}}</a></p> {% endfor %} </body> </html>
- Django 的頁面範本有提供自己的標籤(tag)用來處理視圖傳過來的內容
- `{%` 與 `%}` 通常是 Django 的頁面範本用來做流程控制或資料處理用的標籤,例如++第 6 行++的 `{% for %}` 到++第 8 行++的 `{% endfor %}` 就定義了一個迴圈
- `{% for food in foods %}` 的意思是:從 `foods` 這個資料包裡將其內容項目一項項取出來處理,針對取出來的每一筆資料,暫取將它命名為 `food` 以便待會兒在迴圈內容取用它
- `{% endfor %}` 用來標示迴圈作用的範圍到此結束
- 介於上面兩個標籤之間的內容,就是需要每取到一筆資料項目,都要重覆一次的內容
- 而兩組大括號 `{{` 及 `}}` 則是用來將取得的變數的內容「印」出來
- `{{ food }}`: 將 `food` 變數的內容印出來
- `{{ forloop.counter }}`: 印出是重覆執行的第幾次
8. 新增 `mysite/show/templates/food.html`<html> <head> </head> <body> <img src="/static/food{{kind}}.png"> </body> </html>