本文為 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.idPython ORM 關聯物件的屬性
category_id資料庫層級
category.idPython 層級
category_id高效,直接操作外鍵欄位
category.id可能較慢,涉及額外的資料庫查詢
category_id否
category.id是,需額外查詢關聯的 Category 物件
category_id適合高效篩選條件和查詢
category.id適合訪問關聯物件的屬性或進行更復雜的邏輯操作
如何選擇正確的方式
使用 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 外鍵的使用!如果有其他問題,歡迎提問!