跳轉到

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 官方網站

完整的功能列表和文件可以在官方網站查看:

安裝 Django Extensions

使用 uvdjango-extensions 加入專案:

uv add django-extensions

這個指令會:

  1. 安裝 django-extensions 套件
  2. 自動更新 pyproject.toml
  3. 更新 lock 檔案

IPython 建議一併安裝

shell_plus 在搭配 IPython 使用時會有更好的體驗(語法高亮、自動補全等)。

如果還沒安裝 IPython,可以一起安裝:

uv add ipython --group=dev

設定 Django Extensions

django_extensions 加入 INSTALLED_APPS

core/settings.py
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 識別字規則)

驗證安裝是否成功:

uv run manage.py --help

如果安裝成功,你會在指令列表中看到許多 [django_extensions] 開頭的新指令。

shell_plus:增強的 Django Shell

基本使用

Django 5.2 的改進

從 Django 5.2 開始,一般的 shell 指令也會自動載入專案中的所有 models,不需要手動 import 了!

shell_plus 仍然提供了更多功能,例如 --print-sql 參數可以即時顯示執行的 SQL 查詢。

啟動 shell_plus

uv run manage.py 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 語句:

uv run manage.py shell_plus --print-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 查詢可以幫助你:

  1. 理解 ORM 行為:了解 Django ORM 如何轉換成 SQL
  2. 學習 SQL:透過對照 ORM 和 SQL 來學習資料庫查詢
  3. 除錯:確認查詢是否符合預期
  4. 發現效能問題:在後續章節會學習如何優化查詢效能

更多範例

試試看不同的查詢,觀察對應的 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 的絕佳工具!你可以:

  1. 寫 ORM 查詢
  2. 查看對應的 SQL
  3. 理解 ORM 和 SQL 的對應關係
  4. 逐步掌握 SQL 語法

runserver_plus:增強的開發伺服器

安裝 Werkzeug

runserver_plus 需要 Werkzeug 套件才能使用互動式除錯器:

uv add werkzeug --group=dev

為什麼是 dev group?

Werkzeug 只在開發環境需要,所以加入 --group=dev

正式環境不會使用 runserver_plus,因此不需要安裝 Werkzeug。

基本使用

runserver_plus 提供了比內建 runserver 更強大的功能:

uv run manage.py runserver_plus

主要優勢:

  • 更好的錯誤頁面:顯示更詳細的錯誤資訊
  • 互動式除錯器:可以在錯誤頁面直接執行 Python 程式碼
  • Werkzeug debugger:專業的除錯工具

開發環境限定

runserver_plus 僅適用於開發環境,不可用於正式環境

正式環境應該使用 Gunicorn、uWSGI 等 WSGI 伺服器。

--print-sql:監控所有 SQL 查詢

在開發伺服器中顯示所有執行的 SQL:

uv run manage.py runserver_plus --print-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:

uv run manage.py show_urls

輸出範例:

/                               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 參數改變輸出格式:

表格格式(預設)

uv run manage.py show_urls --format table
URL                              View                            Name
/admin/                          django.contrib.admin.sites...   admin:index
/blog/articles/                  blog.views.article_list         article_list

詳細格式

uv run manage.py show_urls --format verbose
/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 格式

uv run manage.py show_urls --format 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:indexadmin: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 中設定:

core/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:重置資料庫

快速清空並重建資料庫:

uv run manage.py reset_db

資料會全部刪除

這個指令會完全清空資料庫,請小心使用!

sqldsn:顯示資料庫連線資訊

顯示資料庫連線字串:

uv run manage.py sqldsn

clean_pyc:清理 .pyc 檔案

清理所有編譯過的 Python 檔案:

uv run manage.py clean_pyc

更多指令

完整的指令列表可以參考官方文件

這裡只介紹最常用的幾個,其他指令可以根據需要學習。

常見問題

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:

uv add django-extensions --group=dev

然後在 settings.py 中條件式加入:

INSTALLED_APPS = [
    # ...
]

if DEBUG:
    INSTALLED_APPS += ['django_extensions']

但一般建議直接安裝在所有環境,因為它不會影響正式環境運作,只是提供額外的管理指令。

--print-sql 會影響效能嗎?

在開發環境中影響不大,但會:

  • 增加終端機輸出
  • 輕微增加記憶體使用

不應該在正式環境使用 --print-sql,因為:

  • 會記錄大量 SQL 查詢
  • 可能洩漏敏感資料
  • 影響效能

任務結束

完成!

恭喜你完成了這個章節!現在你已經:

  • 了解 Django Extensions 是什麼及其用途
  • 安裝並設定 django-extensions
  • 學習使用 shell_plus 指令
  • 學習使用 show_urls 指令
  • 掌握 SQL 查詢的除錯技巧

開發流程建議

將 Django Extensions 整合到日常開發流程中:

  1. 開發新功能時

    • 使用 runserver_plus --print-sql 即時監控 SQL
    • 觀察頁面執行了哪些資料庫查詢
  2. 測試 ORM 查詢時

    • 使用 shell_plus --print-sql 快速驗證查詢邏輯
    • 確認 SQL 是否符合預期
  3. 新接手專案時

    • 使用 show_urls 快速了解專案路由結構
    • 了解有哪些頁面和功能
  4. 除錯時

    • 使用 runserver_plus 的互動式除錯器
    • 直接在錯誤頁面執行程式碼診斷問題

Django Extensions 是每個 Django 開發者都應該掌握的工具,它能大幅提升開發效率!