Django ORM系統

1. ORM基礎概念

1.1 什么是ORM?

ORM(Object Relational Mapping,對象關系映射)是一種編程技術,用于在面向對象編程語言中實現不同類型系統的數據轉換。在Django中,ORM充當業務邏輯層和數據庫層之間的橋梁。

核心映射關系

  • 類(Class) ? 數據庫表(Table)

  • 類實例(Instance) ? 表記錄(Row)

  • 類屬性(Attribute) ? 表字段(Field)

1.2 ORM的優勢

  1. 開發效率高:不用編寫SQL語句,通過操作對象即可完成數據庫操作

  2. 數據庫解耦:更換數據庫只需修改配置,無需更改業務代碼

  3. 安全性:自動防止SQL注入攻擊

  4. 維護性:模型集中管理,結構清晰

1.3 ORM的劣勢

  1. 性能損耗:相比原生SQL有一定性能損失

  2. 復雜查詢受限:某些復雜查詢難以用ORM表達

  3. SQL能力退化:過度依賴ORM可能導致SQL能力下降

2. Django模型基礎

2.1 模型定義

from django.db import modelsclass Book(models.Model):title = models.CharField(max_length=100)price = models.DecimalField(max_digits=5, decimal_places=2)publish_date = models.DateField(auto_now_add=True)

2.2 常用字段類型

字段類型說明示例
AutoField自增IDid = models.AutoField(primary_key=True)
CharField字符串name = models.CharField(max_length=32)
IntegerField整數age = models.IntegerField()
BooleanField布爾值is_active = models.BooleanField(default=True)
DateField日期birthday = models.DateField()
DateTimeField日期時間created = models.DateTimeField(auto_now_add=True)
EmailField郵箱email = models.EmailField()
TextField長文本content = models.TextField()
ForeignKey外鍵publisher = models.ForeignKey('Publisher')
ManyToManyField多對多authors = models.ManyToManyField('Author')

2.3 字段常用參數

參數說明示例
null數據庫是否可為空null=True
blank表單驗證是否可為空blank=True
default默認值default=0
primary_key是否主鍵primary_key=True
unique是否唯一unique=True
db_index是否創建索引db_index=True
choices可選值列表GENDER_CHOICES = [(0,'男'),(1,'女')]
verbose_name可讀名稱verbose_name='書名'

3. 數據庫操作

3.1 增刪改查(CRUD)

創建數據
# 方法1
Book.objects.create(title='Python入門', price=59.99)# 方法2
book = Book(title='Django高級', price=79.99)
book.save()# 方法3(批量創建)
Book.objects.bulk_create([Book(title='Java基礎', price=49.99),Book(title='C++編程', price=69.99)
])
查詢數據
# 獲取所有
books = Book.objects.all()# 獲取單個(不存在會報DoesNotExist)
book = Book.objects.get(id=1)# 過濾查詢
cheap_books = Book.objects.filter(price__lt=50)# 排除查詢
expensive_books = Book.objects.exclude(price__lt=100)# 排序
books = Book.objects.order_by('-price')# 限制數量
books = Book.objects.all()[:5]
更新數據
# 方法1
Book.objects.filter(id=1).update(price=99.99)# 方法2
book = Book.objects.get(id=1)
book.price = 89.99
book.save()
刪除數據
# 刪除單個
Book.objects.get(id=1).delete()# 批量刪除
Book.objects.filter(price__gt=100).delete()

3.2 高級查詢

雙下劃線查詢
# 范圍查詢
Book.objects.filter(price__range=(50, 100))# 包含查詢
Book.objects.filter(title__contains='Python')# 開頭/結尾查詢
Book.objects.filter(title__startswith='Django')
Book.objects.filter(title__endswith='入門')# 日期查詢
Book.objects.filter(publish_date__year=2023)
Q對象(復雜查詢)
from django.db.models import Q# OR查詢
Book.objects.filter(Q(price__lt=50) | Q(title__contains='Python'))# NOT查詢
Book.objects.filter(~Q(price__gt=100))# 組合查詢
Book.objects.filter(Q(price__lt=50) & Q(title__startswith='Django'))
F對象(字段比較)
from django.db.models import F# 比較兩個字段
Book.objects.filter(price__gt=F('discount_price'))# 字段運算
Book.objects.update(price=F('price') * 1.1)

3.3 聚合與分組

from django.db.models import Count, Avg, Max, Min, Sum# 聚合
Book.objects.aggregate(Avg('price'), Max('price'))# 分組
from django.db.models import Count
Publisher.objects.annotate(book_count=Count('book')).values('name', 'book_count')

4. 表關系操作

4.1 一對一關系

class UserProfile(models.Model):user = models.OneToOneField(User, on_delete=models.CASCADE)phone = models.CharField(max_length=20)# 查詢
profile = user.userprofile
user = profile.user

4.2 一對多關系

class Publisher(models.Model):name = models.CharField(max_length=50)class Book(models.Model):publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)# 正向查詢
book = Book.objects.first()
publisher = book.publisher# 反向查詢
publisher = Publisher.objects.first()
books = publisher.book_set.all()

4.3 多對多關系

class Author(models.Model):name = models.CharField(max_length=50)class Book(models.Model):authors = models.ManyToManyField(Author)# 查詢
book = Book.objects.first()
authors = book.authors.all()author = Author.objects.first()
books = author.book_set.all()# 添加關系
book.authors.add(author)
book.authors.remove(author)
book.authors.clear()
book.authors.set([author1, author2])

4.4 自定義中間表

class BookAuthor(models.Model):book = models.ForeignKey(Book, on_delete=models.CASCADE)author = models.ForeignKey(Author, on_delete=models.CASCADE)created = models.DateTimeField(auto_now_add=True)class Book(models.Model):authors = models.ManyToManyField(Author, through='BookAuthor')

5. 事務與原生SQL

5.1 事務處理

from django.db import transaction# 裝飾器方式
@transaction.atomic
def create_book():# 這里的操作都在一個事務中pass# 上下文管理器方式
def update_book():try:with transaction.atomic():# 事務操作passexcept Exception:# 異常處理pass

5.2 執行原生SQL

from django.db import connection# 查詢
with connection.cursor() as cursor:cursor.execute("SELECT * FROM books WHERE price > %s", [50])rows = cursor.fetchall()# 插入/更新
with connection.cursor() as cursor:cursor.execute("UPDATE books SET price = price * 1.1 WHERE publish_date > %s", ['2023-01-01'])

6. 性能優化

6.1 select_related(外鍵關聯查詢)

# 普通查詢(會產生N+1問題)
books = Book.objects.all()
for book in books:print(book.publisher.name)  # 每次循環都會查詢數據庫# 優化查詢(使用JOIN)
books = Book.objects.select_related('publisher').all()
for book in books:print(book.publisher.name)  # 只查詢一次數據庫

6.2 prefetch_related(多對多關聯查詢)

# 普通查詢
authors = Author.objects.all()
for author in authors:print(author.book_set.all())  # 每次循環都會查詢數據庫# 優化查詢
authors = Author.objects.prefetch_related('book_set').all()
for author in authors:print(author.book_set.all())  # 只查詢兩次數據庫

6.3 only與defer

# 只獲取指定字段
books = Book.objects.only('title', 'price')# 排除指定字段
books = Book.objects.defer('content')

6.4 批量操作

# 批量創建
Book.objects.bulk_create([...])# 批量更新
books = Book.objects.all()
for book in books:book.price *= 1.1
Book.objects.bulk_update(books, ['price'])

7. 實際應用案例

7.1 分頁查詢

from django.core.paginator import Paginatordef book_list(request):page = request.GET.get('page', 1)paginator = Paginator(Book.objects.all(), 10)books = paginator.get_page(page)return render(request, 'book_list.html', {'books': books})

7.2 復雜查詢示例

# 查詢2023年出版的,價格大于50或者標題包含"Python"的書籍
from django.db.models import Q
books = Book.objects.filter(Q(publish_date__year=2023) &(Q(price__gt=50) | Q(title__icontains='Python'))
).order_by('-publish_date')

7.3 自定義管理器

class ActiveBookManager(models.Manager):def get_queryset(self):return super().get_queryset().filter(is_active=True)class Book(models.Model):is_active = models.BooleanField(default=True)objects = models.Manager()  # 默認管理器active = ActiveBookManager()  # 自定義管理器# 使用
active_books = Book.active.all()

8. 常見問題與解決方案

Q1: 如何查看ORM生成的SQL語句?

# 方法1:打印QuerySet的query屬性
print(Book.objects.all().query)# 方法2:配置LOGGING
LOGGING = {'version': 1,'handlers': {'console': {'level': 'DEBUG','class': 'logging.StreamHandler',},},'loggers': {'django.db.backends': {'level': 'DEBUG','handlers': ['console'],},},
}

Q2: 如何優化ORM查詢性能?

  1. 使用select_relatedprefetch_related減少查詢次數

  2. 使用onlydefer限制查詢字段

  3. 合理使用索引(db_index=True

  4. 批量操作代替循環操作

  5. 避免在循環中進行數據庫查詢

Q3: 如何處理大量數據?

# 使用iterator()方法
for book in Book.objects.all().iterator():process(book)# 使用分塊查詢
from django.core.paginator import Paginator
paginator = Paginator(Book.objects.all(), 1000)
for page in paginator.page_range:for book in paginator.page(page).object_list:process(book)

Q4: 如何實現軟刪除?

class SoftDeleteModel(models.Model):is_deleted = models.BooleanField(default=False)def delete(self, using=None, keep_parents=False):self.is_deleted = Trueself.save()class Meta:abstract = Trueclass Book(SoftDeleteModel):# 其他字段...pass# 查詢時排除已刪除
Book.objects.filter(is_deleted=False)

9. 總結

Django ORM是一個功能強大且易于使用的數據庫抽象層,通過本文我們學習了:

  1. 模型定義:如何定義模型和字段

  2. 基本CRUD:創建、讀取、更新和刪除操作

  3. 高級查詢:Q對象、F對象、聚合和分組

  4. 表關系:一對一、一對多和多對多關系的處理

  5. 性能優化:select_related、prefetch_related等技巧

  6. 事務管理:保證數據一致性的方法

  7. 實際應用:分頁、復雜查詢等常見場景

掌握這些知識后,你將能夠高效地使用Django ORM進行數據庫操作,同時保持代碼的清晰和可維護性。記住,ORM是工具,合理使用才能發揮最大價值。

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

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

相關文章

Tailwind CSS中設定寬度和高度的方法

在 Tailwind CSS 中,設定元素的寬度(width)和高度(height)有多種方式,涵蓋固定值、相對值、響應式調整等。以下是完整的方法分類及示例:一、固定寬度 / 高度類以 4px (0.25rem) 為單位遞增&…

Java行為型模式---備忘錄模式

備忘錄模式基礎概念備忘錄模式(Memento Pattern)是一種行為型設計模式,其核心思想是在不破壞封裝性的前提下,捕獲一個對象的內部狀態,并在該對象之外保存這個狀態,以便后續可以將該對象恢復到先前保存的狀態…

后端參數校驗

前端給后端傳輸數據&#xff0c;有時候參數需要校驗&#xff0c;我們自己寫代碼會比較麻煩&#xff0c;我們可以使用springboot為我們提供的注解&#xff0c;降低這些沒有必要的代碼開發。1.引入依賴<dependency><groupId>org.springframework.boot</groupId>…

C++ - 仿 RabbitMQ 實現消息隊列--服務端核心模塊實現(一)

目錄 日志打印工具 實用 Helper 工具 sqlite 基礎操作類 字符串操作類 UUID 生成器類 文件基礎操作 文件是否存在判斷 文件大小獲取 讀文件 寫文件 文件重命名 文件創建/刪除 父級目錄的獲取 目錄創建/刪除 附錄&#xff08;完整代碼&#xff09; 日志打印工具 為了便…

C語言:第07天筆記

C語言&#xff1a;第07天筆記 內容提要 循環結構 break與continue 綜合案例《猜拳游戲》數組 數組的概念一維數組流程控制 break與continue break 功能&#xff1a; ① 用在switch中&#xff0c;用來跳出switch中的case語句&#xff1b;如果case沒有break&#xff0c;可能會產生…

qt 中英文翻譯 如何配置和使用

qt 中英文翻譯 如何配置和使用 1. 在.pro文件中添加TRANSLATIONS 在你的 .pro 文件&#xff08;比如 HYAC_AAF_HOST.pro&#xff09;中添加&#xff1a; TRANSLATIONS \ zh\_CN.ts en\_US.ts這會告訴Qt項目你要支持中文和英文。 2. 提取可翻譯文本&#xff08;生成ts文件&#…

Leetcode 710. 黑名單中的隨機數

1.題目基本信息 1.1.題目描述 給定一個整數 n 和一個 無重復 黑名單整數數組 blacklist 。設計一種算法&#xff0c;從 [0, n - 1] 范圍內的任意整數中選取一個 未加入 黑名單 blacklist 的整數。任何在上述范圍內且不在黑名單 blacklist 中的整數都應該有 同等的可能性 被返…

RxJava 全解析:從原理到 Android 實戰

在 Android 開發中&#xff0c;異步任務處理是繞不開的核心場景 —— 網絡請求、數據庫操作、文件讀寫等都需要在后臺執行&#xff0c;而結果需回調到主線程更新 UI。傳統的 “HandlerThread” 或 AsyncTask 不僅代碼冗余&#xff0c;還容易陷入 “回調地獄”&#xff08;嵌套回…

OpenCV 官翻7 - 對象檢測

文章目錄ArUco 標記檢測標記與字典標記物創建標記檢測姿態估計選擇字典預定義字典自動生成字典手動定義字典檢測器參數閾值處理adaptiveThreshConstant輪廓過濾minMarkerPerimeterRate 與 maxMarkerPerimeterRatepolygonalApproxAccuracyRateminCornerDistanceRateminMarkerDis…

【Oracle】ORACLE OMF說明

ORACLE OMF (Oracle Managed Files) 是 Oracle 數據庫提供的一項自動化文件管理功能。它的核心目的是簡化數據庫管理員&#xff08;DBA&#xff09;對數據庫底層操作系統文件的管理工作。 以下是 OMF 的關鍵要點&#xff1a; 核心功能&#xff1a;自動命名和定位文件 在創建數據…

408考研逐題詳解:2010年第35題——RIP協議

2010年第35題 某自治系統內采用 RIP 協議&#xff0c;若該自治系統內的路由器 R1 收到其鄰居路由器 R2 的距離矢量&#xff0c;距離矢量中包含信息 <net1, 16>&#xff0c;則能得出的結論是&#xff08; &#xff09; A. R2 可以經過 R1 到達 net1&#xff0c;跳數為17 …

http與https的主要區別是什么?

什么是HTTP&#xff1f; HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本傳輸協議&#xff09;是互聯網上應用最為廣泛的一種網絡協議。它構成了Web數據通信的基礎&#xff0c;并定義了客戶端和服務器之間如何請求和傳遞網頁信息。當您在瀏覽器中輸入一個網址時…

STC89C52系列單片機簡介

STC89C52系列單片機是由中國宏晶科技&#xff08;STC&#xff09;推出的一款新一代增強型8051內核單片機。它不僅繼承了傳統8051指令系統的兼容性&#xff0c;還在性能、功耗、抗干擾能力以及性價比方面進行了全面提升&#xff0c;廣泛應用于各類嵌入式控制場景&#xff0c;如工…

基于 Docker 環境的 JupyterHub 詳細部署手冊

本文詳細介紹基于Docker Compose的單機版JupyterHub部署方案&#xff0c;通過容器化技術實現多用戶Notebook環境的快速搭建。方案采用官方JupyterHub鏡像&#xff0c;配置11個端口映射&#xff08;18000-18010&#xff09;支持用戶并發&#xff0c;通過數據卷掛載&#xff08;.…

常見的萬能密碼

目錄 1. 通用SQL注入 2. 登錄繞過 3. 密碼重置 1. 通用SQL注入 or 11-- " or 11-- or aa " or "a""a or 11# " or 11# or 11/* " or 11/* or 11 " or "1""1 2. 登錄繞過 admin-- admin or 11-- admin or aa …

04訓練windows電腦低算力顯卡如何部署pytorch實現GPU加速

大多數人用的電腦的顯卡配置可能沒有那么強,也就是說,我們很難享受到最新版本pytorch給我們帶來的模型訓練的速度和效率,為此,我們需要想辦法在現有顯卡情況下部署應用pytorch。 筆者有一臺電腦,顯卡算力很低,那么以該電腦為例,為大家介紹如何部署應用pytorch功能。 1…

PPT科研畫圖插件

PPT科研畫圖插件 iSlide- 讓PPT設計簡單起來 | PPT模板下載平臺iSlide - 簡單&#xff0c;好用的PPT插件&#xff01;擁有30萬 原創可商用PPT模板&#xff0c;PPT主題素材&#xff0c;PPT案例&#xff0c;PPT圖表&#xff0c;PPT圖示&#xff0c;PPT圖標&#xff0c;PPT插圖和8…

CSS實現背景圖片漸變透明

復合寫法background: linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #FFF 82.5%),url(https://example.com/image.jpg) center / cover no-repeat;參數說明&#xff1a;linear-gradient(180deg, rgba(255, 255, 255, 0) 0%, #FFF 82.5%)創建從下至上的垂直漸變&#xff…

基于pyside6的通用機器人遙控控制界面

1. 前言 這兩天需要幫一個朋友做一個簡單的遙控控制界面&#xff0c;用于控制一臺復合機器人(萬向輪底盤機械臂旋轉云臺)&#xff0c;在這里分享一下 2. 開發框架 由于朋友那邊的控制接口都是使用python來寫的&#xff0c;所以我這里也使用py來完成這個遙控界面的開發。但其…

【iOS】ZARA仿寫

【iOS】ZARA仿寫 文章目錄【iOS】ZARA仿寫前言首頁發現我的對姓名的更改總結前言 暑假第一個的任務仿寫ZARA 雖然不是特別難卻有很多小細節需要注意 首頁 點進程序出現的就是整個項目最主要的一個點&#xff0c;即首頁的無限輪播圖&#xff0c;不管是自動輪播還是手動滑動&a…