Published on

Django (二) 模組功能與基本範例

Authors
  • avatar
    Name
    Ryan Chung
    Twitter

目錄

本篇是 Django 系列文的第二章,其他內容請參考以下連結:

  1. Django (一) 基本介紹與環境架設
  2. Django (二) 模組功能與使用範例
  3. Django (三) 網頁模版與網址設計
  4. Django (四) 資料庫與模型使用
  5. Django (五) 表單設計與整合
  6. Django (六) 用戶登入與社群應用
  7. Django (七) 網站部署與內容管理

Django 架構與功能

基本設定

首先,我們可以根據上一篇教學文,建立第一個 Django 專案 (mysite):

$ django-admin startproject mysite
├── manage.py
└── mysite
    ├── __init__.py
    ├── asgi.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

觀察專案內部可以發現,裡面有一個 manage.py 檔案,以及一個與專案同名的資料夾,內部也放了許多 python 檔案。我們先一個個介紹其功能:

  • manage.py:此 Django 專案內的主要管理程式碼,當我們今天要新增 app 或是啟動 server 都要透過它。
  • mysite 資料夾:與專案名稱相同,負責放一些全域設定。
  • __init__.py:宣告 python 模組,通常無需在意。
  • settings.py:整個專案的全域設定,包含套件管理、app 註冊、Templates 連結、Time zone 等等都會在這裡作設定。
  • urls.py:網址設定檔,設定每個 URL 要對應到的函示。通常每新增一個網頁就需要編輯它。
  • wsgi.py or asgi.py:讓網站上線所需要的介面設定檔,之後會有專文作詳細說明。

如果我們在終端機輸入以下指令:

$ python manage.py runserver #啟動Django伺服器
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

You have 18 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
Run 'python manage.py migrate' to apply them.

Django version 3.2.5, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

終端機會提示你伺服器已經啟動,以及一些 migrations 尚未執行(暫時不用理它)。只要按照提示,開啟瀏覽器並輸入 http://127.0.0.1:8000/ 或是 http://localhost:8000/ ,就會看到你的第一個網頁畫面。

接著,我們來建立第一個 app,你可以簡單的將 app 理解成一個網站。換句話說,這個專案可以同時管理很多網站。

$ python manage.py startapp blog

當我們建立第一個 app 叫 blog,會發現它在專案中創建一個同名資料夾,裡面有許多 python 檔;同時在專案內部多了一個資料庫 db.sqlite3。

├── blog
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── db.sqlite3
├── manage.py
└── mysite
...

然而,光是這樣還無法啟用這個 app,需要自行在專案內進行設定。請用任何程式編輯器 (IDE) 打開 mysite/settings.py,修改以下兩個地方:

# Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog', # <--新增你的app
)

...

# Internationalization

LANGUAGE_CODE = 'zh-Hant' #語言
TIME_ZONE = 'Asia/Taipei' #時區
USE_I18N = True

可以看到 Django 已經預先幫我們安裝了幾個常用 app,像是 admin (管理後台)、auth (登入功能)...。另外,我們還可以將系統語言設定為 zh-Hant (繁體中文),相關規範可以參考 i18n。

輸出頁面

接著,我們先來設定第一個網址。打開 mysite/urls.py,並修改成以下樣式:

from django.contrib import admin
from django.urls import path
from blog import views #匯入你的 blog/view.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', views.hello_world), #新增網址與對應的動作
]

打開 blog/views.py,修改成以下樣式:

from django.shortcuts import render
from django.http import HttpResponse #匯入http模組

def hello_world(request):
    return HttpResponse("Hello World!")

這時重新啟動 server,輸入 http://127.0.0.1:8000/hello/ ,便可以看到你的第一個網頁訊息: Hello World!

然而大家一定會想「我要的是美美的網站,可不是一句沒營養的話。」,所以我們接著來使用一些前端模板來美化我們的網站。

首先新增兩個資料夾 templates、static,static下再新增 js、css、images 資料夾。此時,專案結構應該如下:

├── blog
│   └── ...
├── db.sqlite3
├── manage.py
├── mysite
│   └── ...
├── static
│   ├── css
│   ├── images
│   └── js
└── templates

如此便可以將前、後端劃分開來,方便前端工程師專注在自己的網頁模板設計。其中,templates 資料夾專門放 html 模板。

我們接著打開 mysite/settings.py,修改關於 templates 與 static 的部分:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / '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',
            ],
        },
    },
]

...

# Static files (CSS, JavaScript, Images)

STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"] # <--修改這裡!

以上皆是使用「相對路徑」的方式。如果要使用「絕對路徑」,可以修改為以下形式:

import os
...
os.path.join(BASE_DIR, 'DIR NAME') #將templates、static位置改成這樣

接著我們來新增第一個檔案 templates/hello_world.html:

<!DOCTYPE html>
<html>
    <head>
        <title>hello world!</title>
    </head>
    <body>
        <h1 style="color:red;">這是我的第一個Django網站</h1>
        <hr>
        <h3>現在時刻:{{ time }}</h3>
    </body>
</html>

然後修改 blog/views.py:

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

def hello_world(request):
    time = datetime.now()
    return render(request, 'hello_world.html', locals())

這裡,我們利用 render() 函數來渲染模板,利用 locals() 函數來打包所有變數。改完後結果如下:

美化過的頁面出來了,可以開始設計網頁了~等等!我們還必須學會最後一個東西,那就是 「後端資料庫」

建立資料庫

還記得我們的終極目標是一個社群部落格平台嗎?要建立部落格網站,「文章」本身是不可或缺的,但是我們總不能每次發文都重新寫一個 html 吧?這時就必須使用資料庫來管理我們的文章,再透過 html 模板中的變數,來讀取我們所需要的內容。

請打開 mysite/settings.py,找到 database 的區塊:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

在這裡,可以設定資料庫的引擎 (ENGINE),預設是用 SQLite3,你也可以改成 MySQL、PostgreSQL、Oracle 等其他常用的關聯式資料庫。

接著我們打開 blog/models.py,新增第一個資料模型 Post:

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=100) #文章標題
    slug = models.CharField(max_length=100) #文章網址
    content = models.TextField(blank=True) #文章內容
    date = models.DateTimeField(auto_now_add=True) #發文時間
    
    class Meta:
        ordering = ('-date',)

    def __str__(self):
        return self.title

Post 中要存什麼內容是我們自己設計的。其中,class Meta 是讓文章顯示順序以 date 為依據由新到舊,__str__ 是 python 常用的方式,讓回傳資料有一個顯示的依據(此處是 title )。

建立好 model 後,我們還需要讓它同步到資料庫內。請在終端機執行以下兩行指令:

$ python manage.py makemigrations #建立blog/migrations/0001_initial.py
$ python manage.py migrate #根據檔案同步資料庫

這樣就可以使用資料庫了。但是為了管理方便,Django 還提供一個後台介面供我們直接操作資料。請先輸入以下指令,並按照指示建立管理員帳號:

$ python manage.py createsuperuser

接著,請打開 blog/admin.py,將剛剛建立好的 model 放入後台來管理:

from django.contrib import admin
from .models import Post

class PostAdmin(admin.ModelAdmin): #設定Post介面的外觀
    list_display = ('title','slug','date')

admin.site.register(Post, PostAdmin) #註冊Post model

啟動server後,進入 http://127.0.0.1:8000/admin ,便可以看到後台登入介面。輸入剛剛註冊過的管裡員帳號,就可以看到精美的資料庫頁面。

為了練習方便,我們先在這裡建立幾篇貼文。完成後,我們要讓前端能夠順利看到剛剛寫好的文章,必須重新設定 views 與 templates。

打開 blog/views.py,改寫如下:

from django.shortcuts import render
from django.http import HttpResponse
from datetime import datetime
from .models import Post

def post(request):
    posts = Post.objects.all()
    time = datetime.now()
    return render(request, 'post.html', locals())

設定好網址 mysite/urls.py:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('post/', views.post),
]

新增一個網頁 templates/post.html:

<!DOCTYPE html>
<html>
    <head>
        <title>我的部落格</title>
    </head>
    <body>
        <h1 style="color:red;">這是我的第一個部落格</h1>
        <hr>
        {% for post in posts %} 
        <p style="font-size:16pt; font-weight:bold;">
            {{ post.title }}
        </p>
        <p style="font-size:10pt;">
            {{ post.content }}
        </p>
        {% endfor %} 
        <hr>
        <h3>現在時刻:{{ time }}</h3>
    </body>
</html>

然後就可以進入 http://127.0.0.1:8000/post ,看到剛剛的網頁與文章。

透過以上操作,大家應該可以初步理解 Django 的運作流程。Django 透過 Model、Template、View 形成模組化的 MTV 架構,分別處理不同的功能,讓網站開發變得相當有條理。