Django 外鍵查詢入門:category_id 與 category.id 的區別
更新日期: 2024 年 12 月 24 日
本文為 Django 分類功能系列教學,第 11 篇:
- 新手指南:如何設計 Django 分類功能
- 新手指南:如何定義需求並實現分類模型
- 新手指南:Service 模型與 related_name 的作用
- 新手指南:透過自訂管理指令初始化分類資料
- 自訂管理指令:程式碼詳細解說
- 新手指南:深入理解 get_or_create 的作用與用法
- Django 新手指南:新增分類欄位的邏輯
- Django 新手指南:如何正確編輯服務分類
- Django 新手指南:modelform 數據提交原理解析
- Django 分類頁畫面顯示功能指南
- Django 外鍵查詢入門:category_id 與 category.id 的區別 👈 所在位置
在 Django 中,處理外鍵關聯時,有兩種常見操作方式:直接使用資料庫中的外鍵欄位(如 category_id
),或通過 ORM 訪問關聯物件的屬性(如 category.id
)。
這兩者雖然表面類似,但運作原理和適用場景大不相同。
本篇文章將詳細解析這兩種方式,幫助新手理解如何在不同場景下選擇正確的方式進行查詢和操作。
核心代碼解析
以下代碼展示了兩種查詢方式的區別:
# 方法 1:直接使用資料庫的外鍵欄位
services = Service.objects.filter(category_id=id)
# 方法 2:通過關聯物件的屬性
category = Category.objects.get(id=id)
services = Service.objects.filter(category=category)
兩種方式的詳細解釋
category_id
的查詢邏輯
運作原理
category_id
是 Django ORM 自動生成的資料庫欄位名稱,直接存儲Category
表中關聯物件的主鍵(通常是id
)。- 使用
filter(category_id=id)
,Django 將生成針對資料庫的高效 SQL 查詢,直接過濾外鍵欄位的值。
優點
- 效能更高:
- 直接操作資料庫中的外鍵欄位,無需額外的關聯查詢。
- 寫法簡潔:
- 不需要先查詢
Category
物件即可篩選對應的Service
。
- 不需要先查詢
底層 SQL 查詢
執行以下代碼:
services = Service.objects.filter(category_id=id)
將生成的 SQL:
SELECT * FROM service WHERE category_id = <id>;
category.id
的查詢邏輯
運作原理
category
是Service
模型中的一個關聯物件,代表與之關聯的Category
模型實體。- 當使用
category.id
時,Django 會執行以下步驟:- 從
Service
表中獲取category_id
的值。 - 再根據該值查詢
Category
表,返回對應的Category
物件。
- 從
優點
- 面向物件:
- 符合 Python 的物件導向思維,方便訪問關聯物件的其他屬性(如
name
、created_at
等)。
- 符合 Python 的物件導向思維,方便訪問關聯物件的其他屬性(如
底層查詢行為
執行以下代碼:
service = Service.objects.get(id=1)
category_id = service.category.id
實際上執行了兩次查詢:
- 從
Service
表獲取category_id
的值:
SELECT category_id FROM service WHERE id = 1;
- 根據
category_id
查詢Category
表:
SELECT * FROM category WHERE id = <category_id>;
兩者的主要區別
特性 | category_id | category.id |
---|---|---|
類型 | 資料庫外鍵欄位 | Python ORM 關聯物件的屬性 |
操作層級 | 資料庫層級 | Python 層級 |
效能 | 高效,直接操作外鍵欄位 | 可能較慢,涉及額外的資料庫查詢 |
是否執行額外查詢 | 否 | 是,需額外查詢關聯的 Category 物件 |
適用場景 | 適合高效篩選條件和查詢 | 適合訪問關聯物件的屬性或進行更復雜的邏輯操作 |
如何選擇正確的方式
使用 category_id
的場景
- 高效篩選和查詢:當您需要根據分類篩選服務時,直接使用
category_id
更高效。 - 簡化代碼:避免額外的物件加載,例如:
services = Service.objects.filter(category_id=3)
使用 category.id
的場景
- 需要訪問關聯物件屬性:當需要訪問分類的其他屬性(如名稱、描述)時,可以使用
category
物件:service = Service.objects.get(id=1) print(service.category.name) # 訪問分類名稱
實際應用示例
篩選服務:推薦使用 category_id
# 篩選分類 ID 為 5 的所有服務
services = Service.objects.filter(category_id=5)
顯示服務詳細資訊:需要使用 category
物件
# 顯示服務名稱及其分類名稱
service = Service.objects.get(id=1)
print(f"服務名稱: {service.name}, 所屬分類: {service.category.name}")
結論
category_id
是資料庫層級的外鍵欄位,適合進行高效的查詢和篩選操作。category.id
是 ORM 關聯物件的屬性,適合需要訪問關聯物件屬性時使用。- 根據不同的場景,選擇正確的方式能提升代碼效能與可讀性。
希望本篇文章能幫助您更好地理解 Django 外鍵的使用!如果有其他問題,歡迎提問!