Django Extensions¶
開始之前¶
任務目標
在這個章節中,我們會完成:
- 了解 Django Extensions 是什麼及其用途
- 安裝並設定 django-extensions
- 學習使用 shell_plus 指令
- 學習使用 show_urls 指令
- 掌握 SQL 查詢的除錯技巧
什麼是 Django Extensions?¶
Django Extensions 是一個第三方套件,提供了許多實用的管理指令和工具,讓 Django 開發更加方便高效。
為什麼需要 Django Extensions?¶
| 功能 | 說明 |
|---|---|
| 增強的 Shell | shell_plus 自動載入所有 models,不需要手動 import |
| URL 檢視 | show_urls 顯示所有註冊的 URL patterns |
| SQL 除錯 | --print-sql 即時顯示執行的 SQL 查詢 |
| 開發伺服器增強 | runserver_plus 提供更好的錯誤頁面和互動式除錯 |
| 實用工具 | 還有許多其他實用指令 |
安裝 Django Extensions¶
使用 uv 將 django-extensions 加入專案:
這個指令會:
- 安裝
django-extensions套件 - 自動更新
pyproject.toml - 更新 lock 檔案
IPython 建議一併安裝
shell_plus 在搭配 IPython 使用時會有更好的體驗(語法高亮、自動補全等)。
如果還沒安裝 IPython,可以一起安裝:
設定 Django Extensions¶
將 django_extensions 加入 INSTALLED_APPS:
INSTALLED_APPS = [
# Django 內建 apps
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
# 第三方 apps
"django_bootstrap5",
"django_extensions",
# 本地 apps
"practices",
"blog",
]
注意名稱
套件名稱是 django-extensions(連字號),但在 INSTALLED_APPS 中是 django_extensions(底線)。
這是因為:
- Python 套件名稱使用連字號(pip/uv 安裝時)
- Python import 名稱使用底線(符合 Python 識別字規則)
驗證安裝是否成功:
如果安裝成功,你會在指令列表中看到許多 [django_extensions] 開頭的新指令。
shell_plus:增強的 Django Shell¶
基本使用¶
Django 5.2 的改進
從 Django 5.2 開始,一般的 shell 指令也會自動載入專案中的所有 models,不需要手動 import 了!
但 shell_plus 仍然提供了更多功能,例如 --print-sql 參數可以即時顯示執行的 SQL 查詢。
啟動 shell_plus:
# Shell Plus Model Imports
from blog.models import Article, Author, Tag
from django.contrib.auth.models import User, Group, Permission
# ... 自動載入所有 models ...
Python 3.12.0 (main, Oct 2024)
Type 'copyright', 'credits' or 'license' for more information
IPython 8.18.0 -- An enhanced Interactive Python.
In [1]: Article.objects.all()
Out[1]: <QuerySet [<Article: Django 入門>, <Article: Python 基礎>]>
所有 models 都已經自動載入,可以直接使用!
--print-sql:顯示 SQL 查詢¶
使用 --print-sql 參數可以即時查看執行的 SQL 語句:
現在每個 ORM 查詢都會顯示對應的 SQL:
In [1]: Article.objects.all()
SELECT "blog_article"."id",
"blog_article"."title",
"blog_article"."content",
"blog_article"."author_id",
"blog_article"."created_at",
"blog_article"."updated_at"
FROM "blog_article"
Execution time: 0.001s [Database: default]
Out[1]: <QuerySet [<Article: Django 入門>, <Article: Python 基礎>]>
為什麼要查看 SQL?
查看 SQL 查詢可以幫助你:
- 理解 ORM 行為:了解 Django ORM 如何轉換成 SQL
- 學習 SQL:透過對照 ORM 和 SQL 來學習資料庫查詢
- 除錯:確認查詢是否符合預期
- 發現效能問題:在後續章節會學習如何優化查詢效能
更多範例¶
試試看不同的查詢,觀察對應的 SQL:
# 取得單一文章
In [2]: Article.objects.get(id=1)
SELECT "blog_article"."id", ...
FROM "blog_article"
WHERE "blog_article"."id" = 1
LIMIT 21
# 篩選文章
In [3]: Article.objects.filter(title__contains='Django')
SELECT "blog_article"."id", ...
FROM "blog_article"
WHERE "blog_article"."title" LIKE '%Django%' ESCAPE '\'
# 排序
In [4]: Article.objects.order_by('-created_at')
SELECT "blog_article"."id", ...
FROM "blog_article"
ORDER BY "blog_article"."created_at" DESC
學習 SQL 的好工具
--print-sql 是學習 SQL 的絕佳工具!你可以:
- 寫 ORM 查詢
- 查看對應的 SQL
- 理解 ORM 和 SQL 的對應關係
- 逐步掌握 SQL 語法
runserver_plus:增強的開發伺服器¶
安裝 Werkzeug¶
runserver_plus 需要 Werkzeug 套件才能使用互動式除錯器:
為什麼是 dev group?
Werkzeug 只在開發環境需要,所以加入 --group=dev。
正式環境不會使用 runserver_plus,因此不需要安裝 Werkzeug。
基本使用¶
runserver_plus 提供了比內建 runserver 更強大的功能:
主要優勢:
- 更好的錯誤頁面:顯示更詳細的錯誤資訊
- 互動式除錯器:可以在錯誤頁面直接執行 Python 程式碼
- Werkzeug debugger:專業的除錯工具
開發環境限定
runserver_plus 僅適用於開發環境,不可用於正式環境。
正式環境應該使用 Gunicorn、uWSGI 等 WSGI 伺服器。
--print-sql:監控所有 SQL 查詢¶
在開發伺服器中顯示所有執行的 SQL:
現在當你瀏覽網站時,終端機會即時顯示所有 SQL 查詢:
[06/Dec/2025 10:30:15] "GET /blog/articles/ HTTP/1.1" 200 1234
SELECT "blog_article"."id",
"blog_article"."title",
"blog_article"."content",
"blog_article"."author_id",
"blog_article"."created_at"
FROM "blog_article"
ORDER BY "blog_article"."created_at" DESC
Execution time: 0.003s [Database: default]
SELECT "blog_author"."id", "blog_author"."name"
FROM "blog_author"
WHERE "blog_author"."id" = 1
Execution time: 0.001s [Database: default]
# ... 更多查詢 ...
即時 SQL 監控
這個功能讓你在瀏覽網站時,可以立即看到每個頁面執行了哪些 SQL 查詢。
在後續章節學習效能優化時,這會是非常實用的工具!
show_urls:檢視所有 URL 路由¶
基本使用¶
查看專案中所有註冊的 URL patterns:
輸出範例:
/ core.urls.index index
/admin/ django.contrib.admin.sites.index admin:index
/admin/login/ django.contrib.admin.sites.login admin:login
/admin/logout/ django.contrib.admin.sites.logout admin:logout
/blog/articles/ blog.views.article_list article_list
/blog/articles/<int:article_id>/ blog.views.article_detail article_detail
實用場景
- 檢查路由:確認 URL patterns 是否正確註冊
- 查找 URL name:快速找到特定路由的 name(用於
{% url %}template tag) - 除錯路由問題:當 URL 無法正確對應時,用來檢查路由設定
- 了解專案結構:新接手專案時,快速了解有哪些路由
格式化輸出¶
使用 --format 參數改變輸出格式:
表格格式(預設)¶
URL View Name
/admin/ django.contrib.admin.sites... admin:index
/blog/articles/ blog.views.article_list article_list
詳細格式¶
/blog/articles/
View: blog.views.article_list
Name: article_list
Decorator: None
/blog/articles/<int:article_id>/
View: blog.views.article_detail
Name: article_detail
Decorator: None
JSON 格式¶
[
{
"url": "/blog/articles/",
"view": "blog.views.article_list",
"name": "article_list"
},
{
"url": "/blog/articles/<int:article_id>/",
"view": "blog.views.article_detail",
"name": "article_detail"
}
]
JSON 格式的用途
JSON 格式可以:
- 匯出給其他工具使用
- 產生 API 文件
- 進行自動化測試
URL Namespace 的重要性
注意到輸出中的 admin:index、admin:login 等格式嗎?
這就是 URL namespace,格式為 app_name:url_name。使用 namespace 可以:
- 避免不同 app 的 URL name 衝突
- 讓 URL 結構更清晰
- 在 template 中使用
{% url 'namespace:name' %}引用
我們在之前的章節中使用過 {% url 'admin:index' %},這裡的 admin 就是 namespace,index 是 URL name。
關於如何為自己的 app 設定 namespace,會在後續章節詳細說明。
SQL 輸出長度限制¶
移除長度限制¶
預設情況下,--print-sql 會截斷過長的 SQL 查詢。如果想完整顯示 SQL,可以在 settings.py 中設定:
# 移除 SQL 查詢的長度限制
SHELL_PLUS_PRINT_SQL_TRUNCATE = None
RUNSERVER_PLUS_PRINT_SQL_TRUNCATE = None
設定說明
SHELL_PLUS_PRINT_SQL_TRUNCATE:控制shell_plus --print-sql的輸出長度RUNSERVER_PLUS_PRINT_SQL_TRUNCATE:控制runserver_plus --print-sql的輸出長度- 設定為
None表示不截斷,完整顯示所有 SQL
何時需要調整?
大多數情況下不需要調整這個設定。但在以下情況可能會需要:
- 查詢包含大量欄位或條件
- 需要檢視完整的 SQL 來除錯
- 分析複雜的 JOIN 查詢
其他實用指令¶
Django Extensions 還提供了許多其他實用指令:
reset_db:重置資料庫¶
快速清空並重建資料庫:
資料會全部刪除
這個指令會完全清空資料庫,請小心使用!
sqldsn:顯示資料庫連線資訊¶
顯示資料庫連線字串:
clean_pyc:清理 .pyc 檔案¶
清理所有編譯過的 Python 檔案:
常見問題¶
shell_plus 和一般 shell 有什麼不同?¶
| 特性 | shell | shell_plus |
|---|---|---|
| Models 載入 | Django 5.2+ 自動載入 | 自動載入所有 models |
| 顯示 SQL | 需要額外設定 | --print-sql 即可 |
| 啟動速度 | 快 | 稍慢(需載入所有 models) |
| 適用場景 | 快速測試簡單功能 | ORM 查詢開發和除錯 |
Django 版本差異
Django 5.2 之前的版本,一般的 shell 不會自動載入 models,需要手動 import。
Django 5.2 開始,shell 也會自動載入專案中的 models 了!
runserver_plus 可以用在正式環境嗎?¶
不行。 runserver_plus 僅供開發使用。
正式環境應該使用:
- Gunicorn:Python WSGI HTTP Server
- uWSGI:另一個流行的 WSGI Server
- Nginx:作為反向代理
如何只在開發環境安裝 django-extensions?¶
可以將它加入 dev group:
然後在 settings.py 中條件式加入:
但一般建議直接安裝在所有環境,因為它不會影響正式環境運作,只是提供額外的管理指令。
--print-sql 會影響效能嗎?¶
在開發環境中影響不大,但會:
- 增加終端機輸出
- 輕微增加記憶體使用
不應該在正式環境使用 --print-sql,因為:
- 會記錄大量 SQL 查詢
- 可能洩漏敏感資料
- 影響效能
任務結束¶
完成!
恭喜你完成了這個章節!現在你已經:
- 了解 Django Extensions 是什麼及其用途
- 安裝並設定 django-extensions
- 學習使用 shell_plus 指令
- 學習使用 show_urls 指令
- 掌握 SQL 查詢的除錯技巧
開發流程建議
將 Django Extensions 整合到日常開發流程中:
-
開發新功能時:
- 使用
runserver_plus --print-sql即時監控 SQL - 觀察頁面執行了哪些資料庫查詢
- 使用
-
測試 ORM 查詢時:
- 使用
shell_plus --print-sql快速驗證查詢邏輯 - 確認 SQL 是否符合預期
- 使用
-
新接手專案時:
- 使用
show_urls快速了解專案路由結構 - 了解有哪些頁面和功能
- 使用
-
除錯時:
- 使用
runserver_plus的互動式除錯器 - 直接在錯誤頁面執行程式碼診斷問題
- 使用
Django Extensions 是每個 Django 開發者都應該掌握的工具,它能大幅提升開發效率!