Django 提供了便捷的工具和框架,讓開發者能快速建構 Web 應用程式。本文示範如何利用 Django 建立一個 IP 位址管理系統,涵蓋了模型設計、URL 組態和管理介面的使用。首先,我們定義了 NetworkAddress 模型,包含 IP 位址、網路大小、描述和父級網路等欄位,並使用 manage.py syncdb 指令建立資料函式庫表格。接著,我們探討了 URL 設計原則,建議以應用程式名稱開頭,接著是模型名稱和操作動詞,並示範如何在主 urls.py 和應用程式特定的 urls.py 中組態 URL 對映。最後,我們介紹瞭如何啟用 Django 管理介面,並將 NetworkAddress 模型加入管理介面中,方便開發者快速新增、修改和刪除資料。
建立IP位址統計的Web應用程式
實作基本功能
完成Django安裝和Apache網頁伺服器的設定後,我們可以開始進行Web應用程式的開發。這個過程可以分為以下幾個部分:
- 建立模型(Models)
- 定義URL結構(URL Schema)
- 建立檢視(Views)
在我的經驗中,這個過程是非常迭代的;我會不斷修改模型、新增URL和建立新的檢視,以配合開發的進行。這種方法可以讓我快速地得到可運作的東西,並測試一些功能,即使整個應用程式尚未完成。不要認為這種方法是混亂的;相反地,我只會處理我在設計階段已經識別和寫下的元素。因此,這個過程只是將一大塊工作分解成更小、更容易管理的小塊,可以分開開發和測試。
定義資料函式庫模型
在繼續之前,請回顧表3-1,並檢查我們要在資料模型中使用的欄位。由於Django會自動將物件對映到關聯式資料函式庫,因此我們需要為應用程式中使用的每個概念建立類別定義,這些類別將對映到資料函式庫中的表格。
常用的Django欄位型別
| 欄位類別名稱 | 描述 |
|---|---|
| BooleanField | 只接受True或False值,但在MySQL資料函式庫中,欄位會儲存1或0的值。 |
| CharField | 用於儲存字串,需要設定max_length引數以指定可儲存的最大長度。 |
| DateField | 儲存日期為Python的datetime.date類別例項。可接受auto_now和auto_now_add引數。 |
| DateTimeField | 儲存日期和時間為Python的datetime.datetime例項。使用與DateField相同的可選引數。 |
| DecimalField | 用於儲存固定精確度的十進位數字。需要max_digits和decimal_places引數。 |
| EmailField | 類別似於CharField,但會檢查是否為有效的電子郵件地址。 |
| FileField | 用於儲存上傳的檔案。檔案儲存在檔案系統中,而不是資料函式庫中。 |
| FloatField | 儲存浮點數。 |
| ImageField | 類別似於FileField,但會檢查檔案是否為有效的圖片。需要Python Imaging Library(PIL)。 |
| IntegerField | 儲存整數值。 |
| PositiveIntegerField | 儲存整數值,但只允許正整數。 |
| NullBooleanField | 儲存True、False和None值。 |
| SlugField | 儲存文字,但只允許英數字元、下劃線和連字號。 |
| TextField | 用於儲存大塊文字。 |
| TimeField | 儲存時間為Python的datetime.time例項。可接受與DateField相同的可選引數。 |
| URLField | 用於儲存URL,包括網域名稱。可接受verify_exists引數,以檢查URL是否有效。 |
| XMLField | TextField,會檢查文字是否為有效的XML,並符合RELAX NG定義的XML結構描述。 |
建立資料模型類別
我們只有一個表格,因此讓我們定義一個類別,如清單3-2所示。在models.py檔案中新增以下程式碼。
class NetworkAddress(models.Model):
address = models.IPAddressField()
network_size = models.PositiveIntegerField()
description = models.CharField(max_length=400)
parent = models.ForeignKey('self')
程式碼解析
class NetworkAddress(models.Model):定義一個名為NetworkAddress的類別,繼承自Django的models.Model類別。這使得NetworkAddress成為一個自訂的模型,Django將使用它來建立資料函式庫表格。address = models.IPAddressField():定義一個名為address的欄位,用於儲存IP地址。network_size = models.PositiveIntegerField():定義一個名為network_size的欄位,用於儲存網路大小,且該欄位只允許儲存正整數。description = models.CharField(max_length=400):定義一個名為description的欄位,用於儲存描述資訊,最大長度為400個字元。parent = models.ForeignKey('self'):定義一個名為parent的外部索引鍵,指向NetworkAddress模型自身,用於建立網路地址之間的層級關係。
建立資料函式庫表格
要建立資料函式庫表格,只需使用manage.py工具並加上syncdb選項。當我們第一次執行它時,它還會為設定檔中列出的其他應用程式建立表格。
$ python manage.py syncdb
執行上述指令後,Django會詢問是否要建立一個超級使用者帳號,以用於內建的身份驗證應用程式。
輸出結果
Creating tables ...
Creating table django_admin_log
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session
Creating table ip_addresses_networkaddress
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (leave blank to use 'rytis'):
Email address: [email protected]
Password:
Password (again):
Superuser created successfully.
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
$
建立IP位址帳務網頁應用程式的URL組態
在Django開發過程中,URL組態是一個重要且頻繁修改的部分。為了保持URL組態的可控性和可維護性,需要制定一些基本的規則來定義新的URL。雖然Django提供了完全的控制權,但選擇一個合理的URL結構和命名約定是非常重要的。
URL設計原則
- 以應用程式名稱開始:所有的URL都應該以應用程式的名稱開始,例如
http://www.example.com/ip_addresses/。這樣可以避免不同應用程式之間的URL名稱衝突。 - 模型名稱緊隨其後:在應用程式名稱之後新增模型名稱,如果需要更具體的子集,則在模型名稱後新增篩選條件。盡量避免使用物件ID。例如,
ip_addresses/networkaddress/列出所有頂層網路。 - 操作動詞放在物件名稱之後:如果需要對物件進行操作,在特定物件名稱後新增操作動詞。例如,刪除網路地址的URL可以是
ip_addresses/networkaddress/192.168.0.1/delete。
這些原則可以總結為以下URL結構:
http://www.example.com/<應用程式>/<模型>/<物件>/<動作>/
URL對映組態
URL對映是在urls.py模組中定義的,預設設定如以下範例所示:
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'www_example_com.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
)
內容解密:
from django.conf.urls import patterns, include, url:匯入必要的模組來定義URL模式。admin.autodiscover():自動發現並註冊Django管理後台的模型。urlpatterns = patterns('', ...):定義URL模式的列表,每個條目都是一個URL元組,包含正規表示式、回撥函式和可選的字典。
URL處理流程
當使用者請求一個頁面時,請求被傳送到Apache伺服器,然後呼叫Django處理器。Django框架會遍歷urlpatterns中的所有條目,並嘗試將每個正規表示式與請求的URL進行匹配。當找到匹配時,Django會呼叫與正規表示式相關聯的回撥函式,並傳遞一個HttpRequest物件和可選的從URL中捕捉的引數。
應用程式特定的URL組態
建議不要在主urls.py檔案中定義任何特定於應用程式的URL規則,而是使用應用程式本地的組態。這樣可以將應用程式的URL與網站解耦,使得相同的應用程式可以在不同的專案中重複使用。
例如,在主專案urls.py中:
urlpatterns = patterns('',
[...]
url(r'^ip_addresses/', include('www_example_com.ip_addresses.urls')),
[...]
)
然後在應用程式特定的組態檔案ip_addresses/urls.py中:
urlpatterns = patterns('',
[...]
)
內容解密:
url(r'^ip_addresses/', include('www_example_com.ip_addresses.urls')):將所有以ip_addresses/開頭的URL請求轉發到ip_addresses/urls.py進行進一步處理。urlpatterns = patterns('', ...):在應用程式特定的urls.py檔案中定義具體的URL模式。
這種解耦方式使得應用程式的URL組態更加靈活和可重用。
使用管理介面
在建立用於顯示記錄的檢視和表單,以及新增和刪除記錄之前,我們先來啟用 Django 的管理介面。這是一個非常實用的工具,提供了對資料的即時存取,具有豐富的功能,可以新增、刪除、修改、搜尋和篩選儲存在資料函式庫中的記錄。在開發階段也非常有用,可以讓你在建立新增記錄的表單之前,先新增記錄和建立顯示檢視。
啟用管理介面
注意:在早期版本的 Django 中,預設情況下管理介面是停用的。在較新的版本中,管理介面會自動啟用,因此你不需要做任何事情。雖然如此,還是建議你按照以下步驟進行設定,以熟悉設定檔的結構。
要啟用管理介面,你需要做以下幾件事:將管理介面新增到網站設定的應用程式清單中,啟用 URL 規則,並設定 Apache 以提供管理介面的靜態內容(主要是 CSS 和 JS 指令碼)。你需要修改 settings.py 模組中的 INSTALLED_APPS 清單,使其包含管理介面包:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'ip_addresses',
)
完成後,你需要重新執行 syncdb 命令,以便在資料函式庫中建立管理應用程式所需的新表格:
$ python manage.py syncdb
Creating table django_admin_log
Installing index for admin.LogEntry model
$
接下來,你需要在 urls.py 模組中取消註解所有與管理介面相關的行,並確保其內容類別似於清單 3-4。
清單 3-4:在 urls.py 模組中啟用管理介面
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'www_example_com.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
# ip_addresses application
url(r'^ip_addresses/', include('ip_addresses.urls')),
)
你需要在 DocumentRoot 目錄中建立一個符號連結,以便 Apache 可以從 URL www.example.com/static/admin 提供 /opt/local/django-trunk/django/contrib/admin/media 的內容:
$ ln –s /usr/share/django/django/contrib/admin/media \
/var/www/virtual/www.example.com/static/admin
完成這些準備工作後,你應該可以瀏覽到 www.example.com/admin 並看到管理介面的登入頁面,如圖 3-2 所示。
圖 3-2:Django 管理介面登入頁面
你可以使用先前執行 syncdb 時建立的管理員帳戶登入。登入後,你將看到基本的使用者和網站管理選項,如圖 3-3 所示。
允許管理介面管理新模型
你可能已經注意到,Django 管理介面尚未提供任何選項來管理 NetworkAddress 模型。這是因為它尚未找到任何相關的指示。要將任何資料模型類別新增到管理介面非常簡單;你只需要建立一個新的 Python 模組 admin.py 在你的應用程式目錄中,並包含如清單 3-5 所示的程式碼。
清單 3-5:將 NetworkAddress 類別新增到管理介面
from www_example_com.ip_addresses.models import NetworkAddress
from django.contrib import admin
class NetworkAddressAdmin(admin.ModelAdmin):
pass
admin.site.register(NetworkAddress, NetworkAddressAdmin)
內容解密:
- 首先,我們從標準的 Django 包中匯入
NetworkAddress類別和管理模組。 - 然後,我們為每個要置於管理模組控制下的模型定義一個管理類別。管理類別的命名慣例是
<Model class name>Admin。這個類別必須繼承自admin.ModelAdmin類別,該類別定義了模型管理介面的預設行為。 - 在我們的簡單模型中,無需調整預設行為。它允許基本的檢視/新增/刪除/修改功能,並且因為我們將建立自己的介面,具有額外的功能(例如以層次結構顯示資訊),所以我們不需要從 Django 管理模組中獲得額外的功能。
你可以嘗試使用自動產生的介面;嘗試新增新條目和修改現有的條目。同時,嘗試輸入無效資訊,例如格式錯誤的 IP 位址,並檢查 Django 管理介面如何對錯誤做出反應。你會注意到無效的 IP 位址不被接受;然而,沒有邏輯檢查網路大小是否在適用範圍內:1-32。(我們將需要在表單層級使用驗證,我稍後會描述。)
圖 3-3:Django 管理介面的預設檢視
你可以利用這個自動產生的介面進行一些操作,例如新增和修改記錄。同時,你也可以嘗試輸入錯誤的資料,例如不正確的 IP 位址,以觀察 Django 管理介面的反應。雖然它可以正確地拒絕無效的 IP 位址,但是它並沒有檢查網路大小是否在合理的範圍內(1-32)。這個問題將在稍後的表單驗證階段得到解決。