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 开发领域更游刃有余。如果你在使用过程中有新的发现或遇到问题,欢迎在评论区交流分享!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/pingmian/81913.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

A10服务器使用vllm推理框架成功运行Qwen3大模型

1.下载Qwen3大模型: git clone https://www.modelscope.cn/Qwen/Qwen3-1.7B.git放在服务器的/mnt/workspace/Qwen3-1.7B目录下。 2.创建python虚拟环境: python3 -m venv venv1 source venv1/bin/activate3.安装vllm推理框架 pip install vllm 4.启动…

Disruptor—1.原理和使用简介

大纲 1.Disruptor简介 2.Disruptor和BlockingQueue的压测对比 3.Disruptor的编程模型 4.Disruptor的数据结构与生产消费模型 5.RingBuffer Disruptor Sequence相关类 6.Disruptor的WaitStrategy消费者等待策略 7.EventProcessor EventHandler等类 8.Disruptor的运行…

谷歌浏览器调试python pygui程序

谷歌浏览器地址:chrome://inspect/#devices 前端vue为8080, 配置如下 pychat 需要配置环境变量 PYTHONUNBUFFERED1;QTWEBENGINE_REMOTE_DEBUGGING9012

手写Tomcat(二)—Tomcat简化模型架构

一、 Tomcat架构 Tomcat的主要角色是 servlet容器,提供一个解释器,能够解析并执行JavaScript Object Notation (JON)脚本(后更改为Servlet),并将请求传送到指定的服务器(如JavaBean)。因此&…

Android 网络全栈攻略(五)—— 从 OkHttp 拦截器来看 HTTP 协议二

上一篇我们介绍了 OkHttp 的责任链以及第一个内置拦截器 —— 重试与重定向拦截器。本篇我们将剩余四个拦截器的解析做完。 1、桥接拦截器 BridgeInterceptor 作为请求准备和实际发送之间的桥梁,自动处理 HTTP 请求头等繁琐工作。比如设置请求内容长度&#xff0c…

JDBC-java操作数据库

1.基本结构: package com.atguigu.servlets;import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement;public class JDBCemo {public static void main(String[] args) throws Exception{String url "jdbc:mysql:///mysql&qu…

七彩喜适老化改造:让每个空间成为长者尊严的守护者

随着我国老龄化进程的加速,居家养老逐渐成为老年人首选的生活方式。 为了让老年人能够在熟悉的环境中安享晚年,适老化改造应运而生。 七彩喜作为居家养老服务的创新者,致力于通过科学设计和人性化改造,为老年人提供安全、舒适、…

【动态规划】5 从一次函数出发推导斜率优化dp

背景 基于例题《任务安排》逐步推导进行斜率优化。 引入 例题:P2365 任务安排 考虑动态规划。使用 d p i , j dp_{i,j} dpi,j​ 表示前 i i i 个任务分了 j j j 段的最小费用。 显然,有 d p i , j min ⁡ k 1 i − 1 ( d p i , j , d p k , j…

MySQL中实现大数据量的快速插入

一、SQL语句优化​ 1. ​批量插入代替单条插入​ ​单条插入会频繁触发事务提交和日志写入,效率极低。​批量插入通过合并多条数据为一条SQL语句,减少网络传输和SQL解析开销。 -- 低效写法:逐条插入 INSERT INTO table (col1, col2) VALUE…

C++23中std::span和std::basic_string_view可平凡复制提案解析

文章目录 一、引言二、相关概念解释2.1 平凡复制(Trivially Copyable)2.2 std::span2.3 std::basic_string_view 三、std::span和std::basic_string_view的应用场景3.1 std::span的应用场景3.2 std::basic_string_view的应用场景 四、P2251R1提案对std::…

广东省省考备考(第十八天5.23)—言语:语句填空题(听课后强化训练)

错题 解析 横线出现在文段中间,需结合上下文内容进行分析。文段开篇指出逃离北上广深的话题时而出现,一些人离开大城市回到小城市。随后通过转折词“但”引出横线内容,且结合横线后人才倾向于向更发达的地方流动的内容,横线处应体…

持续更新 ,GPT-4o 风格提示词案例大全!附使用方式

本文汇集了各类4o风格提示词的精选案例,从基础指令到复杂任务,从创意写作到专业领域,为您提供全方位的参考和灵感。我们将持续更新这份案例集,确保您始终能够获取最新、最有效的提示词技巧。 让我们一起探索如何通过精心设计的提…

创建型:建造者模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 工作流程 2.3 实现案例 2.4 变体:链式建造者(常见于多参数对象,无需指挥者) 3、优缺点分析 4、适用场景 1、核心思想 目的:将复杂对象的构建过程与其表示分离…

力扣-长度最小的子数组

1.题目描述 2.题目链接 LCR 008. 长度最小的子数组 - 力扣(LeetCode) 3.题目分析 这道题目我们使用的也是双指针。我们可以定义两个指针都指向数组第一个元素,然后使用right指针遍历原数组,计算left指针到right指针之间的所有元…

JAVA开发工具延长方案

亲测稳定的延长方案与避坑指南 真的搞不懂了,说点专业的术语竟然成了 QINQUAN。那就直接点,把这个方案带给需要的开发者。 延长工具直通车 保姆级教程 延长方案https://mp.weixin.qq.com/s/uajM2Y9Vz6TnolzcLur_bw还是让大家看看,发什么会被…

SpringAI开发SSE传输协议的MCP Server

SpringAI 访问地址:Spring AI ‌ Spring AI‌是一个面向人工智能工程的应用框架,由Spring团队推出,旨在将AI能力集成到Java应用中。Spring AI的核心是解决AI集成的根本挑战,即将企业数据和API与AI模型连接起来‌。 MCP…

JAVA动态生成类

在java的加载过程一般都是要预先定义java类,然后通过经过加载->连接->初始化三步。连接过程又可分为三步:验证->准备->解析。初始化的类是不允许修改。但是在日常的工作中有时候需要动态生成类,那第这种情况怎么办呢? 可以这么处理: 1、先定义一个空的类,仅…

深入解析Java微服务架构:Spring Boot与Spring Cloud的整合实践

深入解析Java微服务架构:Spring Boot与Spring Cloud的整合实践 引言 随着云计算和分布式系统的快速发展,微服务架构已成为现代软件开发的主流模式。Java作为企业级应用开发的核心语言,结合Spring Boot和Spring Cloud,为开发者提…

03_基础篇-NumPy(下):深度学习中的常用操作

03_基础篇-NumPy(下):深度学习中的常用操作 通过上节课的学习,我们已经对NumPy数组有了一定的了解,正所谓实践出真知,今天我们就以一个图像分类的项目为例,看看NumPy的在实际项目中都有哪些重要…

时钟识别项目报告(深度学习、计算机视觉)

深度学习方式 一、模型架构 本模型采用双任务学习框架,基于经典残差网络实现时钟图像的小时和分钟同步识别。 主干网络 使用预训练的ResNet18作为特征提取器,移除原分类层(fc层),保留全局平均池化后的512维特征向量。…