当前位置: 首页 > article >正文

Django 中的 ORM 基础语法

深入剖析 Django 中的 ORM 语法:从基础到实战进阶

在 Django 开发领域,ORM(对象关系映射)是开发者高效操作数据库的得力工具。它以简洁直观的 Python 代码,替代繁琐的 SQL 语句,极大提升了开发效率。本文将聚焦 Django 中的 ORM 语法,通过丰富的示例与场景分析,助你全面掌握其核心用法与进阶技巧。

一、Django ORM 基础架构

1.1 模型类定义

Django 通过models.py文件定义模型类,每个模型类对应数据库中的一张表,类属性则对应表中的列。例如,定义一个简单的博客文章模型:

from django.db import modelsclass Article(models.Model):title = models.CharField(max_length=200)content = models.TextField()pub_date = models.DateTimeField(auto_now_add=True)

上述代码中,title使用CharField表示固定长度的字符串字段;content通过TextField存储长文本;pub_date采用DateTimeField记录文章发布时间,auto_now_add=True确保在创建记录时自动填充当前时间。

1.2 字段类型详解

Django 提供了丰富的字段类型,除上述类型外,还有:

  • IntegerField:用于存储整数值,如文章的点赞数。
  • BooleanField:表示布尔值,常用于标记文章是否置顶、是否为精华内容等。
  • ForeignKey:建立表与表之间的一对多关系,例如文章与作者的关联。
  • ManyToManyField:处理多对多关系,如文章与标签之间的关系。

定义外键关系示例:

class Author(models.Model):name = models.CharField(max_length=100)class Article(models.Model):title = models.CharField(max_length=200)content = models.TextField()author = models.ForeignKey(Author, on_delete=models.CASCADE)

on_delete=models.CASCADE表示当关联的作者被删除时,其对应的文章也会被级联删除。

二、Django ORM 常见操作语法

2.1 创建数据

创建数据实例有两种常见方式。第一种是直接实例化模型类并调用save方法:

author = Author(name="张三")
author.save()article = Article(title="Django ORM入门", content="...", author=author)
article.save()

第二种是使用create方法,该方法在创建实例的同时保存到数据库:

article = Article.objects.create(title="Django ORM实战", content="...", author=author)

2.2 查询数据

2.2.1 基础查询

获取所有文章:

all_articles = Article.objects.all()

获取单篇文章(通过主键):

article = Article.objects.get(pk=1)

注意,使用get方法时若记录不存在会抛出DoesNotExist异常,若存在多条符合条件的记录则会抛出MultipleObjectsReturned异常,因此需谨慎使用。

2.2.2 条件查询

Django 支持丰富的查询条件,通过双下划线(__)连接字段和查询条件:

  • 精确匹配:查询标题为 “Django ORM 实战” 的文章
    articles = Article.objects.filter(title="Django ORM实战")
  • 模糊查询:查询标题包含 “Django” 的文章
    articles = Article.objects.filter(title__icontains="Django")

icontains表示不区分大小写的包含查询,还有contains(区分大小写)、startswith(以... 开头)、endswith(以... 结尾)等类似条件。

  • 范围查询:查询发布时间在某一范围内的文章
  • from django.utils import timezone
    articles = Article.objects.filter(pub_date__range=(timezone.now() - timezone.timedelta(days=7), timezone.now()))

2.3 更新数据

先获取实例,修改属性后调用save方法:

article = Article.objects.get(pk=1)
article.title = "更新后的文章标题"
article.save()

也可以使用update方法批量更新:

Article.objects.filter(pub_date__lt=timezone.now() - timezone.timedelta(days=30)).update(is_published=False)

2.4 删除数据

删除单个实例:

article = Article.objects.get(pk=1)
article.delete()

批量删除:

Article.objects.filter(pub_date__lt=timezone.now() - timezone.timedelta(days=365)).delete()

三、Django ORM 进阶应用

3.1 关联关系操作

3.1.1 一对多关系

以上述Author和Article的一对多关系为例,查询某个作者的所有文章:

author = Author.objects.get(pk=1)
articles = author.article_set.all()

反向查询,即通过文章获取作者:

article = Article.objects.get(pk=1)
author = article.author
3.1.2 多对多关系

定义文章与标签的多对多关系:

class Tag(models.Model):name = models.CharField(max_length=50)class Article(models.Model):title = models.CharField(max_length=200)content = models.TextField()tags = models.ManyToManyField(Tag)

为文章添加标签:

article = Article.objects.get(pk=1)
tag1 = Tag.objects.create(name="Django")
tag2 = Tag.objects.create(name="ORM")
article.tags.add(tag1, tag2)

查询包含特定标签的文章:

articles = Article.objects.filter(tags__name="Django")

3.2 聚合与分组查询

聚合查询用于计算总和、平均值、计数等统计信息,需导入django.db.models中的聚合函数:

  • 统计文章总数
from django.db.models import Count
article_count = Article.objects.count()
  • 计算文章平均点赞数(假设 Article 模型有 likes 字段)
from django.db.models import Avg
average_likes = Article.objects.aggregate(Avg('likes'))

分组查询结合annotate方法使用,例如统计每个作者的文章数量:

from django.db.models import Count
authors_with_article_count = Author.objects.annotate(article_count=Count('article'))
for author in authors_with_article_count:print(f"{author.name} 发表了 {author.article_count} 篇文章")

3.3 事务处理

Django 通过transaction.atomic装饰器或上下文管理器确保数据库操作的原子性。例如,同时更新文章和作者信息:

from django.db import transaction@transaction.atomic
def update_article_and_author():with transaction.atomic():article = Article.objects.get(pk=1)article.title = "更新后的文章标题"article.save()author = article.authorauthor.name = "更新后的作者名"author.save()

若在事务块内发生异常,所有操作将回滚,保证数据一致性。

四、Django ORM 性能优化策略

4.1 避免 N+1 问题

N+1 问题常出现在处理关联关系查询时。例如,获取所有作者及其文章,若不优化会执行 1 次查询获取作者列表,再为每个作者执行 1 次查询获取其文章,导致大量数据库查询。

使用select_related优化一对多关系查询:

authors = Author.objects.select_related('article').all()

prefetch_related用于优化多对多或反向一对多关系:

articles = Article.objects.prefetch_related('tags').all()

4.2 索引优化

根据常用查询条件,在模型字段上添加索引可显著提升查询性能。例如,为文章标题字段添加索引:

class Article(models.Model):title = models.CharField(max_length=200, db_index=True)content = models.TextField()pub_date = models.DateTimeField(auto_now_add=True)

通过db_index=True即可为该字段创建索引,但需注意索引并非越多越好,过多索引会影响数据插入和更新性能。

五、总结

Django 的 ORM 语法功能强大且灵活,从基础的数据增删改查,到复杂的关联关系处理、聚合分组查询,再到性能优化,都为开发者提供了高效便捷的解决方案。在实际项目中,熟练掌握这些语法和技巧,能帮助我们构建出性能优良、易于维护的数据库驱动应用。随着对 Django ORM 理解的深入,不断在实践中探索,你将在 Web 开发领域更游刃有余。如果你在使用过程中有新的发现或遇到问题,欢迎在评论区交流分享!

相关文章:

Django 中的 ORM 基础语法

深入剖析 Django 中的 ORM 语法:从基础到实战进阶 在 Django 开发领域,ORM(对象关系映射)是开发者高效操作数据库的得力工具。它以简洁直观的 Python 代码,替代繁琐的 SQL 语句,极大提升了开发效率。本文将…...

C#对象初始化语句:优雅创建对象的黑科技

📌 核心概念速览 对象初始化语句(Object Initializer)是C#中一种简洁高效的语法糖,允许在创建对象时直接初始化其公有字段或属性,无需依赖构造函数的重载。它的本质是对构造过程的扩展,尤其适合需要灵活设…...

【计算机网络】TCP如何保障传输可靠性_笔记

文章目录 一、传输可靠性的6方面保障二、分段机制三、超时重传机制四、流量控制五、拥塞控制 提示:以下是本篇文章正文内容,下面案例可供参考 源网站 按TCP/IP 4层体系,TCP位于传输层,为应用层提供服务 一、传输可靠性的6方面保障…...

Robust Kernel Estimation with Outliers Handling for Image Deblurring论文阅读

Robust Kernel Estimation with Outliers Handling for Image Deblurring 1. 论文的研究目标与实际问题意义1.1 研究目标1.2 实际问题与产业意义2. 论文的创新方法、模型与优势2.1 核心思路2.2 关键公式与技术细节2.2.1 非线性模糊模型与能量函数2.2.2 中间潜像更新与IRLS2.2.3…...

Android Studio 开发环境兼容性检索(AGP / Gradle / Kotlin / JDK)

本表检索了 Android 项目中常用构建工具的兼容性关系,包括: AGP(Android Gradle Plugin)Gradle(构建工具)KGP(Kotlin Gradle Plugin)JDK(Java Development Kit&#xff…...

html主题切换小demo

主题切换功能为网页和应用程序提供了多样化的视觉风格与使用体验。实现多主题切换的技术方案丰富多样&#xff0c;其中 CSS 变量和 JavaScript 样式控制是较为常见的实现方式。 以下是一个简洁的多主题切换示例&#xff0c;愿它能为您的编程之旅增添一份趣味。 代码展示 <…...

AI架构职责分配——支持AI模块的职责边界设计

职责分配——支持AI模块的职责边界设计 在传统系统中&#xff0c;职责分配通常围绕“控制层处理逻辑、服务层执行业务、数据层持久化”进行划分。这种分工逻辑在纯业务系统中足以支撑高效协作与系统演进。然而&#xff0c;随着AI模块的引入&#xff0c;系统中新增了如模型推理…...

git@gitee.com: Permission denied (publickey). fatal: 无法读取远程仓库

错误信息&#xff1a; gitgitee.com: Permission denied (publickey). fatal: 无法读取远程仓库。 &#xfffc; &#xfffc;说明 Git 无法通过 SSH 密钥成功连接到 Gitee&#xff08;码云&#xff09;仓库。这通常是由于 SSH 密钥未正确配置或未添加到 Gitee 账户所致。 &am…...

CARIS HIPS and SIPS 12.1是专业的多波束水深数据和声呐图像处理软件

CARIS HIPS 和 SIPS 是一套综合水文处理软件&#xff0c;主要用于海洋水道处理和测量领域‌。该软件集成了测深、水柱和海底图像处理功能&#xff0c;能够提高业务处理的精确度和效率‌。 主要功能和应用场景 ‌测深数据处理‌&#xff1a;HIPS主要用于处理大型测深数据。 ‌…...

Docker端口映射与容器互联

Docker端口映射与容器互联 1. 端口映射实现容器访问 1.1 从外部访问容器应用 # 基础端口映射语法 docker run -d -p [宿主机端口]:[容器端口] [镜像名称]# 示例&#xff1a;容器80端口→宿主机8080 docker run -d -p 8080:80 nginx1.2 高级映射配置 映射类型命令示例说明文档…...

在 Ubuntu 24.04 LTS 上 Docker 部署 DB-GPT

一、DB-GPT 简介 DB-GPT 是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL(Agentic Workflow Expression Language) and Agents)。目的是构建大模型领域的基础设施&#xff0c;通过开发多模型管理(SMMF)、Text2SQL效果优化、RAG框架以及…...

使用 Docker 搭建 PyWPS 2.0 服务全流程详解

使用 Docker 搭建 PyWPS 2.0 服务全流程详解 近年来&#xff0c;随着地理信息系统&#xff08;GIS&#xff09;和在线空间分析服务的兴起&#xff0c;OGC标准下的Web Processing Service&#xff08;WPS&#xff09;逐渐成为地理数据服务的重要组件。PyWPS 是一个基于 Python …...

Axure高保真CRM客户关系管理系统原型

一套出色的CRM&#xff08;客户关系管理&#xff09;系统&#xff0c;无疑是企业管理者掌控客户动态、提升销售业绩的得力助手。今天&#xff0c;就为大家介绍一款精心打造的Axure高保真CRM客户关系管理系统原型模板&#xff0c;助你轻松开启高效客户管理之旅。 这款CRM原型模…...

自学嵌入式 day 23 - 数据结构 树状结构 哈希表

一、树状结构 1.特征&#xff1a;在任意一个非空树中&#xff0c; &#xff08;1&#xff09;&#xff0c;有且仅有一个特定的根结点 &#xff08;2&#xff09;&#xff0c;当n>1 时&#xff0c;其余结点可分为m个互不相交的有限集合T1,T2,T3.。。。。Tm&…...

JavaScript进阶(十二)

第三部分:JavaScript进阶 目录 第三部分:JavaScript进阶 十二、深浅拷贝 12.1 浅拷贝 12.2 深拷贝 1. 通过递归实现深拷贝 2. js库lodash里面cloneDeep内部实现了深拷贝 3. 通过JSON.stringify()实现 十三、异常处理 13.1 throw抛异常 13.2 try /catch捕获异常 1…...

Honeywell CV-DINA-DI1624-2A 数字输入模块

概述 型号&#xff1a;CV-DINA-DI1624-2A 类型&#xff1a;数字输入模块&#xff08;16通道&#xff0c;24V DC&#xff09; 制造商&#xff1a;霍尼韦尔&#xff08;Honeywell&#xff09;&#xff0c;属于其工业自动化或楼宇控制系统产品线。 主要功能&#xff1a; 采集16路数…...

中文域名25周年,取得哪些里程碑式的进展?

二十五载中文域名路 第八届中文域名创新应用论坛在北京举办。与会领导专家回顾了中文域名发展历史&#xff0c;深入探讨了当下面临的机遇与挑战&#xff0c;并展望了未来的发展。 自2000年中国推出全球首个中文域名试验系统以来&#xff0c;中文域名已走过25年历程&#xff0c…...

HTTP协议接口三种测试方法之-postman

HTTP协议作为现代Web开发的基石,其接口测试是开发过程中不可或缺的环节。Postman作为最流行的API测试工具之一,能够极大提升我们的测试效率。本文将详细介绍如何使用Postman进行HTTP接口测试。 一、HTTP协议基础回顾 在开始使用Postman之前,我们先简单回顾下HTTP协议的基本…...

【Linux cmd】查看 CPU 使用率的几个命令

1、查看 CPU 使用情况 dstat -c usr 用户sys 系统idl 空闲 2、查看最占 CPU 的进程 dstat --top-cpu...

架空线路监控系统是针对高压架空输电线路设计的一种安全监测解决方案

一、系统介绍 架空线路监控系统是在传统电网线路传输结构的基础上&#xff0c;增设的线路传输无线监控装置。它能够对高压传输线路自身危险点进行监控&#xff0c;也可以对线路闪络、线路舞动、线路二次回流、高压漏电等电力传输故障进行综合检验&#xff0c;是现代电力传输安…...

Kotlin Compose Button 实现长按监听并实现动画效果

想要实现长按按钮开始录音&#xff0c;松开发送的功能。发现 Button 这个控件如果去监听这些按下&#xff0c;松开&#xff0c;长按等事件&#xff0c;发现是不会触发的&#xff0c;究其原因是 Button 已经提前消耗了这些事件所以导致&#xff0c;这些监听无法被触发。因此为了…...

应对进行性核上性麻痹,健康护理铸就温暖防线

进行性核上性麻痹&#xff08;PSP&#xff09;是一种罕见的神经退行性疾病&#xff0c;主要影响患者的运动、平衡及吞咽等功能。针对这类患者&#xff0c;有效的健康护理对提升其生活质量、延缓病情发展至关重要。 在日常生活护理方面&#xff0c;由于患者存在平衡障碍和肌肉僵…...

python邮件地址检验 2024年信息素养大赛复赛/决赛真题 小学组/初中组 python编程挑战赛 真题详细解析

python邮件地址检验 2024全国青少年信息素养大赛Python编程挑战赛复赛真题解析 博主推荐 所有考级比赛学习相关资料合集【推荐收藏】 1、Python比赛 信息素养大赛Python编程挑战赛 蓝桥杯python选拔赛真题详解 蓝桥杯python省赛真题详解 蓝桥杯python国赛真题详解 2、…...

CAD球体功能梯度材料3D插件

插件介绍 CAD球体功能梯度材料3D插件可在AutoCAD内建立大小呈现梯度分布的球体及长方体孔隙三维模型。 功能梯度材料&#xff08;FGM&#xff09;模型包含大小梯度变化的球体及与之适配的长方体部件&#xff0c;可用于球体材料的梯度分布或梯度多孔结构材料建模。 插件支持…...

自制操作系统day9内存管理(cache、位图、列表管理、内存的释放)(ai辅助整理)

day9内存管理 整理源文件&#xff08;harib06a&#xff09; 残留问题&#xff1a;鼠标指针的叠加处理不太顺利&#xff0c;以后处理 先介绍cache&#xff08;高速缓存&#xff09; 每次访问内存&#xff0c;都将所访问的地址和内容存入高速缓存&#xff0c; 往内存里写入数据…...

JavaWebsocket-demo

Websocket客户端 pom依赖 <dependency><groupId>org.java-websocket</groupId><artifactId>Java-WebSocket</artifactId><version>1.4.0</version></dependency>客户端代码片段 Component Slf4j public class PositionAlarmL…...

特征学习:赋予机器学习 “慧眼” 的核心技术

一、特征学习&#xff1a;从人工设计到智能发现的范式革新 1.1 核心定义与价值 特征学习的本质是让机器模仿人类大脑的认知过程 —— 例如&#xff0c;人类视觉系统通过视网膜→视神经→大脑皮层的层级处理&#xff0c;从像素中识别物体&#xff1b;特征学习则通过神经网络的卷…...

3D个人简历网站 7.联系我

3D个人简历网站 7.联系我 修改Contact.jsx // 从 react 库导入 useRef 和 useState hooks import { useRef, useState } from "react";/*** Contact 组件&#xff0c;用于展示联系表单&#xff0c;处理用户表单输入和提交。* returns {JSX.Element} 包含联系表单的 …...

软考中级软件设计师——计算机系统篇

一、数据的表示和运算 1、进制转换 1. 常见进制类型 二进制&#xff08;B&#xff09;&#xff1a;基数为2&#xff08;0,1&#xff09;&#xff0c;计算机底层使用。 八进制&#xff08;O&#xff09;&#xff1a;基数为8&#xff08;0-7&#xff09;&#xff0c;3位二进制…...

甘特图(项目计划图)

甘特图是甘特在第一次世界大战时为了提供工人效率所创。 由时间&#xff08;顶部横坐标&#xff09;和工作事项&#xff08;左边纵坐标组成&#xff09; 假设&#xff0c;我要做大数据迁移&#xff08;一般半年&#xff0c;几PB的数据和上万个任务&#xff09; 类似于这种...