Django ORM 詳解:從入門到進階,掌握數據庫操作的核心

在 Django 中,ORM(Object Relational Mapping,對象關系映射) 是框架的核心之一。它允許你使用 Python 代碼來操作數據庫,而無需編寫原始 SQL 語句。Django ORM 不僅簡化了數據庫操作,還提升了代碼的可讀性、可維護性和安全性。

本文將帶你從基礎到進階,全面了解 Django ORM 的使用方式,包括模型定義、字段類型、查詢操作、聚合函數、關系映射、性能優化等內容。


一、什么是 Django ORM?

ORM 是一種編程技術,它將數據庫中的表映射為 Python 類,表中的行映射為類的實例,字段映射為類的屬性。

在 Django 中:

  • 每個模型(Model)對應數據庫中的一張表;
  • 每個模型實例對應表中的一條記錄;
  • 每個模型類的屬性對應表中的字段。

優點:

  • 跨數據庫兼容:支持多種數據庫(PostgreSQL、MySQL、SQLite、Oracle);
  • 避免 SQL 注入:ORM 會自動處理參數化查詢;
  • 提高開發效率:用 Python 代碼操作數據庫,無需寫 SQL;
  • 結構清晰:模型定義清晰,易于維護。

二、定義模型(Model)

示例:定義一個博客文章模型

from django.db import modelsclass Author(models.Model):name = models.CharField(max_length=100)email = models.EmailField(unique=True)def __str__(self):return self.nameclass Post(models.Model):title = models.CharField(max_length=200)content = models.TextField()author = models.ForeignKey(Author, on_delete=models.CASCADE)published = models.BooleanField(default=True)created_at = models.DateTimeField(auto_now_add=True)updated_at = models.DateTimeField(auto_now=True)def __str__(self):return self.title

常見字段類型:

字段類型

說明

CharField

字符串字段,必須指定 max_length

TextField

長文本字段

IntegerField

整數

BooleanField

布爾值(True/False)

DateTimeField

時間日期字段,auto_now_add

自動設置創建時間,auto_now

自動更新時間

EmailField

郵箱字段,自動驗證格式

ForeignKey

外鍵,用于建立一對多關系

ManyToManyField

多對多關系

OneToOneField

一對一關系


三、字段選項(Field Options)

字段可以設置各種選項,控制其行為:

選項

說明

null=True

允許該字段為 NULL(數據庫層面)

blank=True

表單驗證時允許為空(Django 層面)

default=...

設置默認值

unique=True

字段值必須唯一

verbose_name='中文名'

字段的可讀名稱,用于管理界面

help_text='說明文字'

表單幫助信息

choices=...

限制字段的取值范圍,如性別字段

示例:

GENDER_CHOICES = (('M', '男'),('F', '女'),
)class Profile(models.Model):gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

四、模型關系

Django ORM 支持三種主要的關系類型:

1. 一對一(OneToOneField)

class User(models.Model):username = models.CharField(max_length=100)class UserProfile(models.Model):user = models.OneToOneField(User, on_delete=models.CASCADE)bio = models.TextField()

2. 一對多(ForeignKey)

class Post(models.Model):author = models.ForeignKey(Author, on_delete=models.CASCADE)

3. 多對多(ManyToManyField)

class Tag(models.Model):name = models.CharField(max_length=30)class Post(models.Model):tags = models.ManyToManyField(Tag)

五、查詢操作(QuerySet)

Django ORM 提供了強大的查詢 API,可以使用鏈式調用構建復雜的查詢。

1. 基本查詢

Post.objects.all()                # 獲取所有文章
Post.objects.get(id=1)            # 獲取主鍵為 1 的文章(不存在會拋異常)
Post.objects.filter(title='Django') # 過濾標題為 Django 的文章
Post.objects.exclude(title='SQL')   # 排除標題為 SQL 的文章

2. 查詢條件(Field Lookups)

條件

示例

說明

__exact

title__exact='Django'

精確匹配

__iexact

title__iexact='django'

忽略大小寫匹配

__contains

title__contains='Python'

包含字符串

__icontains

title__icontains='python'

忽略大小寫包含

__gt

price__gt=100

大于

__gte

price__gte=100

大于等于

__lt

price__lt=100

小于

__lte

price__lte=100

小于等于

__in

id__in=[1,2,3]

在某個列表中

__isnull

name__isnull=True

判斷是否為 NULL

3. 排序與切片

Post.objects.order_by('title')            # 按標題升序
Post.objects.order_by('-title')           # 按標題降序
Post.objects.all()[:5]                    # 取前5條記錄

4. 聚合查詢(Aggregate)

from django.db.models import Count, Avg, Max, Min, SumPost.objects.aggregate(Avg('id'))         # 平均值
Post.objects.aggregate(Max('id'))         # 最大值
Post.objects.annotate(count=Count('author')) # 按作者統計文章數量

六、Meta 元類配置

通過 class Meta 可以配置模型的元信息:

class Post(models.Model):title = models.CharField(max_length=200)class Meta:db_table = 'blog_posts'             # 自定義表名ordering = ['-created_at']          # 默認排序verbose_name = '博客文章'verbose_name_plural = '博客文章列表'

七、模型方法

你可以在模型中定義自定義方法,用于封裝業務邏輯:

class Person(models.Model):first_name = models.CharField(max_length=50)last_name = models.CharField(max_length=50)def full_name(self):return f"{self.first_name} {self.last_name}"

八、遷移(Migrations)

每次修改模型后,需要運行遷移命令更新數據庫結構:

# 生成遷移文件
python manage.py makemigrations# 應用遷移
python manage.py migrate

九、性能優化技巧

1. 使用 select_related()(用于 ForeignKey)

Post.objects.select_related('author').all()

2. 使用 prefetch_related()(用于 ManyToManyField)

Post.objects.prefetch_related('tags').all()

3. 使用 only()defer()

Post.objects.only('title', 'author')  # 只加載部分字段
Post.objects.defer('content')         # 排除某些字段

4. 使用 exists() 判斷是否存在

Post.objects.filter(title='Django').exists()

十、總結

Django ORM 是一個強大而靈活的數據庫抽象層,它讓開發者可以用 Python 代碼操作數據庫,極大提升了開發效率和代碼可維護性。

本文我們講解了:

  • ORM 的基本概念和優勢
  • 如何定義模型、字段和關系
  • 查詢操作(filter、exclude、order_by 等)
  • 聚合與統計
  • Meta 元類配置
  • 模型方法
  • 遷移命令
  • 性能優化技巧

掌握 Django ORM 是使用 Django 構建 Web 應用的關鍵技能。接下來你可以深入學習:

  • 自定義查詢(Raw SQL、extra)
  • 數據庫函數(如 Concat、Substr)
  • 使用事務(transaction)
  • 使用數據庫索引優化查詢性能

十一、參考資料

Models | Django documentation | Django

QuerySet API reference | Django documentation | Django

LearnDjango | LearnDjango.com

Page not found | LearnDjango.com

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94269.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94269.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94269.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mac中使用gvm install沒有效果

問題表現: mac使用了gvm install一直沒有效果(添加代理也沒效果),效果如下圖所示,始終卡在downloading,但是gvm version是正常的解決辦法: 手動安裝go的版本(版本號自行選擇&#xf…

【React】狀態管理

兩個狀態管理工具: dva 是一個基于 Redux 和 React Router 的數據流方案,它提供了對 Redux 和 React Router 的封裝,使得在使用 dva 時可以更方便地進行狀態管理和路由操作。React Redux是一個JavaScript狀態管理庫,它的核心包括s…

?CVPR2025 FreeUV:無真值 3D 人臉紋理重建框架

📄論文題目:FreeUV: Ground-Truth-Free Realistic Facial UV Texture Recovery via Cross-Assembly Inference Strategy ??作者及機構:Xingchao Yang、Takafumi Taketomi、Yuki Endo、Yoshihiro Kanamori(CyberAgent、Universit…

Google Chrome <140.0.7297.0 MediaStreamTrackImpl UAF漏洞

【高危】Google Chrome <140.0.7297.0 MediaStreamTrackImpl UAF漏洞 漏洞描述 Google Chrome 是美國谷歌&#xff08;Google&#xff09;公司的一款Web瀏覽器。 受影響版本中&#xff0c;當處理媒體流時&#xff0c;MediaStreamTrackImpl 組件在銷毀前&#xff0c;未能清…

在VSCode中定制C語言宏格式化

在編寫C語言代碼時,經常會遇到一些宏定義的問題,特別是當使用宏來簡化變量聲明時。假設你有一個宏定義如下: #define VAR(vartype, memclass) vartype VAR(float32, AUTOMATIC) var1; // 等同于 "float32 var1;"當你使用VSCode的Format Document</

LangChain4J入門:使用SpringBoot-start

這是連續的專欄內容 &#xff08;一&#xff09;提換依賴 將原有的 <!-- LangChain4j OpenAI 集成 --><dependency><groupId>dev.langchain4j</groupId><artifactId>langchain4j-open-ai</artifactId></dependency> 換成 <!…

AR-Align-NN-2024

文章目錄An unsupervised multi-view contrastive learning framework with attention-based reranking strategy for entity alignment摘要1. 引言2. 相關工作2.1. 實體對齊2.2 對比學習中的數據增強3. 問題定義4. 方法論4.1 嵌入初始化4.2 圖譜數據增強4.3 多視圖對比學習4.4…

DeFi借貸協議深度解析:原理與Python實現

目錄 DeFi借貸協議深度解析:原理與Python實現 1. DeFi借貸協議概述 2. 核心數學原理 2.1 抵押率計算 2.2 健康因子 2.3 利率模型 3. 協議核心組件 3.1 資金池架構 3.2 狀態變量 4. 核心功能實現 4.1 存款功能 4.2 借款功能 4.3 利息計算與更新 5. 清算機制實現 5.1 清算邏輯 5…

信創及一次ORACLE到OB的信創遷移

信創及一次ORACLE到OB的信創遷移 1.信創是什么? 2.銀行信創要求:核心目標與挑戰 3.一次ORACLE到OceanBase(OB)的信創遷移方案 3.0.目標: 3.1.遷移評估OceanBase Migration Assessment (OMA) 3.2.數據對象遷移 3.3.數據遷移 3.4.OceanBase 導數工具 3.5.調用存儲過程跑批 3…

[Python] -進階理解10- 用 Python 實現簡易爬蟲框架

網絡爬蟲是自動抓取網頁并提取數據的程序。本篇文章將基于 Python,從請求、解析和數據流控制三個核心模塊出發,逐步構建一個簡易爬蟲框架,并輔以代碼示例與擴展建議,適合初學者快速掌握爬蟲架構設計。 一、爬蟲架構總覽 典型爬蟲框架包含以下模塊流程: Seed URLs:初始化…

oracle備庫主機斷電重啟后IO異常報錯

兩節點rac adg環境4個實例&#xff0c;節點1異常重啟后IO報錯 檢查控制文件為0字節&#xff0c;第一感覺是不是控制文件損壞了&#xff1f;但節點2說是沒有報錯&#xff0c;理論上如果控制文件壞了&#xff0c;庫應該掛掉了。 嘗試重啟另外一共adg實例&#xff0c;發現讀取其它…

簡單線性回歸模型原理推導(最小二乘法)和案例解析

線性回歸是一種用于建模自變量與因變量之間線性關系的統計方法&#xff0c;核心是通過最小化誤差平方和估計模型參數。以下從數學原理推導和案例兩方面詳細說明。 一、線性回歸模型的數學原理推導 1. 模型定義 線性回歸假設因變量 y 與自變量 x 存在線性關系&#xff0c;具體…

主成分分析法 PCA 是什么

主成分分析法 PCA 是什么 主成分分析法(Principal Component Analysis,簡稱PCA)是一種數據降維與特征提取方法,核心思想是通過線性變換將高維數據映射到低維空間,在盡可能保留原始數據“信息量”(即方差)的同時,減少數據維度,消除特征間的相關性。 主成分分析法(PC…

Elasticsearch太重?試試輕量、極速的Meilisearch

在構建現代化的應用時&#xff0c;“搜索”早已不再是錦上添花的功能&#xff0c;而是決定用戶留存體驗的關鍵一環。Meilisearch&#xff0c;作為一款專為速度、易用性與開發者體驗而生的開源搜索引擎&#xff0c;正受到越來越多開發者的青睞。 本文將介紹 Meilisearch 的核心…

車載通信架構 ---車內通信的汽車網絡安全

我是穿拖鞋的漢子,魔都中堅持長期主義的汽車電子工程師。 老規矩,分享一段喜歡的文字,避免自己成為高知識低文化的工程師: 做到欲望極簡,了解自己的真實欲望,不受外在潮流的影響,不盲從,不跟風。把自己的精力全部用在自己。一是去掉多余,凡事找規律,基礎是誠信;二是…

MySQL: with as與with RECURSIVE如何混合使用?

文章目錄一、with用法系列文章二、前言三、MySQL 普通CTE與遞歸CTE混合使用的嚴格規則四、解決方案4.1、方法1&#xff1a;嵌套查詢4.2、方法2&#xff1a;使用臨時表4.3、方法3&#xff1a;分開執行&#xff08;應用層處理&#xff09;本文主要探討mysql中with普通cte與遞歸ct…

腕管綜合征 : “鼠標手”| “數字時代工傷”,在我國視頻終端工作者中患病率達12%到15%。“

文章目錄 引言 I 預防“鼠標手” 肌腱的滑動 正中神經的滑動 II “鼠標手”是怎么發生的? 癥狀 “鼠標手”的高發人群 引言 “鼠標手”發展到晚期會對神經造成不可逆的損傷。 早期剛開始有癥狀,比如說輕微的麻木,持續的時間也不長,發作頻率也不高的情況下,我們可以通過像…

#C語言——刷題攻略:牛客編程入門訓練(三):輸出格式化、基本運算符

&#x1f31f;菜鳥主頁&#xff1a;晨非辰的主頁 &#x1f440;學習專欄&#xff1a;《C語言刷題合集》 &#x1f4aa;學習階段&#xff1a;C語言方向初學者 ?名言欣賞&#xff1a;"代碼行數決定你的下限&#xff0c;算法思維決定你的上限。" 目錄 1. 牛牛的空格分…

【ELasticsearch】集群故障模擬方案(二):磁盤空間滿、重選主節點

《集群故障模擬方案》系列&#xff0c;共包含以下文章&#xff1a; 1?? 集群故障模擬方案&#xff08;一&#xff09;&#xff1a;節點宕機、節點離線2?? 集群故障模擬方案&#xff08;二&#xff09;&#xff1a;磁盤空間滿、重選主節點 &#x1f60a; 如果您覺得這篇文章…

React中的Hooks

在React 16.8版本之前&#xff0c;組件主要分為兩種&#xff1a;類組件&#xff08;Class Components&#xff09; 和 函數組件&#xff08;Function Components&#xff09;。類組件可以使用 state 來管理內部狀態&#xff0c;也能使用生命周期方法&#xff08;如 componentDi…