Django 中的 ORM 基础语法

news2025/5/24 6:43:13

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

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

一、Django ORM 基础架构

1.1 模型类定义

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

from django.db import models

class 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.author
        author.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.coloradmin.cn/o/2384419.html

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

相关文章

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

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

html主题切换小demo

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

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

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

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

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

在 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框架以及…

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…

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

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

windows服务器部署jenkins工具(一)

jenkins作为一款常用的构建发布工具&#xff0c;极大的简化了项目部署发布流程。jenkins通常是部署在linux服务上&#xff0c;今天给大家分享的是windows服务器上如何搭建jenkins发布工具。 1.首先第一步还是看windows安装docker 这篇文章哈&#xff0c;当然也可以不采用docke…

基于51单片机和8X8点阵屏、独立按键的飞行躲闪类小游戏

目录 系列文章目录前言一、效果展示二、原理分析三、各模块代码1、8X8点阵屏2、独立按键3、定时器04、定时器1 四、主函数总结 系列文章目录 前言 用的是普中A2开发板。 【单片机】STC89C52RC 【频率】12T11.0592MHz 【外设】8X8点阵屏、独立按键 效果查看/操作演示&#xff…