2017年7月23日 星期日

使用 Django 建立網站(二):建立第一個自定義的頁面

在前一篇當中,我們已經產生了一個叫做 myweb 的專案,接著要建立一個應用程式(App)。
這部份基本上也可以參考 Django 官方的教學文件 [1]。

專案(Project)與應用程式(App)的關係為何?

其實因為本來我在看文件時,都會跳著看我需要的部份,所以忽略了其中一小部份細節,導致花了很多時間實驗為什麼結果不如預期
而被我忽略的地方就是 Project 和 App 這段。

在 Django 當中,一開始透過 startproject 指令建立的是 Project,也就是前一篇當中建立的 myweb。
但 Project 裡面又可以建立 App,那麼 Project 跟 App 的差別在哪呢?

從 [1] 的官方文件中,對於 Project 和 App 差異的描述如下。

What’s the difference between a project and an app? An app is a Web application that does something – e.g., a Weblog system, a database of public records or a simple poll app. A project is a collection of configuration and apps for a particular website. A project can contain multiple apps. An app can be in multiple projects.

具體來說,其實我也不知道該怎麼分類 Project 跟 App,不過依據浪費的時間告訴我的是,實作應該要寫在 App 裡
Project 只是用來建立整個網站的全域設定用的。

PS. 這是目前我的理解,當然這也不一定完全正確。

接著這裡先跳一下,來比較一下 Project 的資料夾和 App 的資料夾的差異。

首先是 Project 的資料夾:

[project_name]
 ├─── __init__.py
 ├─── settings.py
 ├─── urls.py
 └─── wsgi.py

再來是 App 的資料夾:

[app_name]
 ├─── migrations
       └─── __init__.py
 ├─── __init__.py
 ├─── admin.py
 ├─── apps.py
 ├─── models.py
 ├─── tests.py
 └─── views.py

其實從資料夾的結構也可以看出,Project 跟 App 的功能完全不同,例如 Project 並沒有 Admin 介面等等。

建立並設定應用程式(App)
建立應用程式

要建立 App,需要透過 startapp 指令來建立。這裡先假設要建立的 App 是部落格,所以就命名成 blog 吧。

python manage.py startapp blog

這樣就建好一個應用程式了 XD。可以檢查一下,正常來說 Django 應該會幫忙產生好上述的 App 資料夾。

在應用程式中建立預設的首頁

在 App 資料夾中,可以找到 view.py 這個檔案(也就是在這個例子中,位在 /blog/views.py)
可以在裡面先寫上一個最簡單的 Hello World~XD

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.
def index(request):
     return HttpResponse("Hello world")

在 views.py 裡追加了 index 這個函式,並且指定輸出 “Hello world” 這個字串。
這樣就完成一個只會吐出 Hello world 字樣的頁面了。

為剛剛建立的頁面設定連結

接著要告訴 Django,當網站的哪些連結被存取時,要回覆 index 給客戶端。
這裡會分成兩個階段的工作,第一個階段是在 App 當中建立規則,第二個階段則是在 Project 中建立規則。

首先是在 App 中建立規則的部份,因為 Django 對於網址的規則習慣用 urls.py 檔案,因此這裡依循習慣也使用 urls.py 來建立。
在 blog 資料夾中建立一個新的檔案 urls.py(亦即 /blog/urls.py)後,在裡面寫上下述的程式碼:

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$', views.index, name='index'),
]

這段程式碼的重點在於第六行,也就是宣告當存取這個 App 時
只要網址符合指定的正規表示式 “^$” 的條件,就以 views.index() 這個函式來服務他
而 views.index() 當然如上述所說,只會回覆 Hello world 字樣。

再來第二階段是要在 Project myweb 裡註冊 blog 這個 App,否則 Project 不知道遇到什麼網址時要讓客戶端存取 blog。
這時要在 myweb 的資料夾中,修改 urls.py(亦即 /myweb/urls.py)。

"""assetmgmt URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url, include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^blog/', include('blog.urls'))
]

這裡為了表示這個 Project 的 urls.py 跟前面提到的 App 的 urls.py 不同,因此連檔案裡本來就有的註解也一起貼上來 XD。
這段主要增加的是第 21 行的部份,不過這裡宣告的是當網址遇到滿足 “^blog/” 時,就引用 blog.urls 的規則進來

綜合上面的兩個 urls.py 後,實際效果就是若網址輸入像是 http://127.0.0.1:8000/blog/ 時,就會呼叫 blog 這個 App 了。
而 blog.urls 裡定義任意字串都去呼叫 views.index 函式,所以 http://127.0.0.1:8000/blog/ 就會顯示出 Hello world 了。

啟動 Django 伺服器

最後,要啟動 Django 的網頁伺服器才能真的在瀏覽器上看出效果。

python manage.py runserver

不過因為截圖很麻煩,所以就…略過了 XD。總之正常應該會出現一個空白頁面,上面只有寫 Hello world 這樣。

參考資料
  1. Writing your first Django app, part 1

沒有留言: