--- --- <style> .markdown-body img:not(.emoji) { border-radius: 5px; box-shadow: 1px 1px 5px dimgrey; } </style> # Django專案 ## 建立專案 1. 開啟「命令提示字元」 在電腦的功能選單中找到並執行「命令提示字元」或者按快捷鍵 <kbd>Win</kbd>+<kbd>R</kbd> 叫出「執行」對話框,在「開啟(O)」後方的文字方塊輸入「`cmd`」來執行命令提示字元 ![image](https://hackmd.io/_uploads/ry2j55GU0.png) ![image](https://hackmd.io/_uploads/HyCR5czLR.png) 2. 切換至欲建立專案的資料夾 在命令提示字元的視窗中,輸入以下指令: ```bash d: cd 11149 ``` - `d:` 表示要先切換至 D 磁碟機 - `cd` 指令用來變更工作資料夾(Change Directory),後方跟著的是想去的資料夾路徑,請依自己實際的狀況變更,不要照抄 3. 建立專案 ```bash django-admin startproject mysite ``` - `django-admin` 是安裝完 django 開發框架後,由框架提供的一個命令列管理工具 - `startproject` 是告訴管理工具說我們想要建立一個新的專案 - `mysite` 是要建立的專案名稱,可以自行命名 打完指令後,會產生一個與專案名稱同名的資料夾,此例名為 `mysite` 的資料夾,其資料夾架構大致如下: ```bash 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` 表示伺服器要綁定的位址及埠號 若成功執行,應該會看到如下畫面: ![](https://i.imgur.com/S9zjic3.png) 3. 開啟瀏覽器,在網址列輸入`http://localhost/`,主機會回應 Django 網站畫面如下: ![image](https://hackmd.io/_uploads/H1oOZsGIA.png) :::info :bulb: 要先啟動專案(管理腳本的 `runserver` 命令),不然瀏覽器看不到東西噢! ::: --- ## 建立應用程式 我們要建立一個圖文展示的應用程式,在命令提示字元按 <kbd>Ctrl</kbd>+<kbd>C</kbd> 中止網站服務,並重新輸入以下指令: ```bash python manage.py startapp show ``` - `startapp` 這是我們學到的 `manage.py` 管理腳本的第 2 個命令,用來在專案內新增一個應用程式(App) - `show` 欲新增的應用程式名稱,可自行需要自行命名 下了這個指令後,會在專案資料夾 `mysite` 底下自動新增一個 `show` 資料夾,整個專案的檔案結構如下: ```bash 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 行++: ```python=31 # 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` 裡面已有的設定如下: ```python=17 from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ] ``` 新增++第 19, 23 行++: ```python=17 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` 將其修改為以下程式碼: ```python= from django.shortcuts import render from django.http import HttpResponse # Create your views here. def homepage(request): return HttpResponse('歡迎光臨魏小良的網站') ``` 在終端機輸入以下指令以執行網站服務: ```bash python manage.py runserver 0.0.0.0:80 ``` 然後在瀏覽器的網址列中輸入 `http://localhost/` 來測試你的網站,應該會看到這行訊息: ![](https://i.imgur.com/GcB6zOu.png) ## 使用模版(頁面範本) 1. 在 `mysite` 專案資料夾下建立模版目錄 `templates`,新增後整個專案的資料夾結構應該如下(省略 `mysite`, `show` 等子資料夾的內容): ```bash= mysite/ manage.py mysite/ show/ templates/ ``` 2. 修改 `mysite/mysite/settings.py` ++第 58 行++: ```python=55 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= <html> <head> </head> <body> 歡迎光臨我的網站 </body> </html> ``` 4. 修改 `show/views.py` ```python= from django.shortcuts import render # Create your views here. def homepage(request): return render(request, 'index.html') ``` ## 餐廳網站 假設我們現在要做一個簡單的餐廳網站,網站首頁會顯示餐廳提供的 3 種餐點。點按餐點名稱的連結後,可以看到該餐點的圖片。 1. 建立靜態檔案目錄 `static` 2. 請將下面 3 張圖片下載並複製到 `static/` 資料夾內。 |圖片|檔名| |:-:|:-:| |![](https://i.imgur.com/X0wgFEg.png)|food1.png| |![](https://i.imgur.com/OmT9F7W.png)|food2.png| |![](https://i.imgur.com/XwYLjjs.png)|food3.png| 3. 修改專案設定檔 `mysite/settings.py` 來指定靜態檔案的存放路徑。 ```python=116 # 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` 前面有定義過,它的內容就是這個專案資料夾的路徑 :::info :bulb: 什麼是靜態檔案? 靜態檔案指的是在網站上幾乎不會變動的內容,像是網站上使用的 Logo 圖片,參考的外部 CSS 檔案以及引用的外部 Javascript 檔,或是提供使用者下載的 Word 文件,PDF檔等等。 ::: 4. 修改專案路徑規則檔 `mysite/urls.py` ```python=17 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` 應用程式的路徑規則: ```python= 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`,變更為以下內容: ```python= 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` 是前面路徑規則從路徑中擷取到的資訊: ```python=5 path('food/<int:kind>', views.food) ``` 7. 修改 `mysite/template/index.html` ++第 5-8 行++: ```html= <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 }}`: 印出是重覆執行的第幾次 ![image](https://hackmd.io/_uploads/HJlgp8N8A.png) 8. 新增 `templates/food.html` ```html= <html> <head> </head> <body> <img src="/static/food{{kind}}.png"> </body> </html> ```