Web框架开发-Django-model进阶

一、QuerySet

可切片

使用python的切片语法来限制查询集记录的数目,它等同于SQL的limit和offset子句。

1

2

In [2]: Book.objects.all()[:5]        # (LIMIT 5)       

            

 In [2]: Book.objects.all()[5:10]     # (OFFSET 5 LIMIT 5)

不支持负的索引(例如Entry.objects.all()[-1])。通常,查询集 的切片返回一个新的查询集 —— 它不会执行查询。

可迭代

1

2

3

4

publish_list = models.Publish.objects.all()  # 查询出所有的出版社对象

for publish_obj in publish_list:

    print(publish.title)

  

惰性查询

查询集 是惰性执行的 —— 创建查询集不会带来任何数据库的访问。你可以将过滤器保持一整天,直到查询集 需要求值时,Django 才会真正运行这个查询。

1

2

3

4

5

6

queryResult=models.Publish.objects.all()

print(queryResult)        # hits database

for book_obj in queryResult:

    print(book_obj.title)        # hits database

  一般来说,只有在“请求”查询集 的结果时才会到数据库中去获取它们。当你确实需要结果时,查询集 通过访问数据库来求值。 

缓存机制

每个查询集都包含一个缓存来最小化对数据库的访问。理解它是如何工作的将让你编写最高效的代码。

在一个新创建的查询集中,缓存为空。首次对查询集进行求值 —— 同时发生数据库查询 ——Django 将保存查询的结果到查询集的缓存中并返回明确请求的结果(例如,如果正在迭代查询集,则返回下一个结果)。接下来对该查询集 的求值将重用缓存的结果。

请牢记这个缓存行为,因为对查询集使用不当的话,它会坑你的。例如,下面的语句创建两个查询集,对它们求值,然后扔掉它们:

1

2

print([a.title for in models.Article.objects.all()])

print([a.create_time for in models.Article.objects.all()])

 

这意味着相同的数据库查询将执行两次,显然倍增了你的数据库负载。同时,还有可能两个结果列表并不包含相同的数据库记录,因为在两次请求期间有可能有Article被添加进来或删除掉。为了避免这个问题,只需保存查询集并重新使用它:

1

2

3

queryResult=models.Article.objects.all()

print([a.title for in queryResult])

print([a.create_time for in queryResult])

何时查询集不会被缓存?

查询集不会永远缓存它们的结果。当只对查询集的部分进行求值时会检查缓存, 如果这个部分不在缓存中,那么接下来查询返回的记录都将不会被缓存。所以,这意味着使用切片或索引来限制查询集将不会填充缓存。

例如,重复获取查询集对象中一个特定的索引将每次都查询数据库:

1

2

3

>>> queryset = Book.objects.all()

>>> print queryset[5# Queries the database

>>> print queryset[5# Queries the database again

然而,如果已经对全部查询集求值过,则将检查缓存:  

1

2

3

4

>>> queryset = Book.objects.all()

>>> [entry for entry in queryset] # Queries the database

>>> print queryset[5# Uses cache

>>> print queryset[5# Uses cache

下面是一些其它例子,它们会使得全部的查询集被求值并填充到缓存中:  

1

2

3

4

>>> [book for book in queryset]

>>> bool(queryset)

>>> book in queryset

>>> list(queryset)

注:简单地打印查询集不会填充缓存。  

1

2

3

queryResult=models.Book.objects.all()

print(queryResult) #  hits database

print(queryResult) #  hits database

exists()与iterator()方法

exists:

简单的使用if语句进行判断也会完全执行整个queryset并且把数据放入cache,虽然你并不需要这些 数据!为了避免这个,可以用exists()方法来检查是否有数据:

1

2

3

if queryResult.exists():

   #SELECT (1) AS "a" FROM "blog_article" LIMIT 1; args=()

       print("exists...")

iterator:

当queryset非常巨大时,cache会成为问题。

处理成千上万的记录时,将它们一次装入内存是很浪费的。更糟糕的是,巨大的queryset可能会锁住系统 进程,让你的程序濒临崩溃。要避免在遍历数据的同时产生queryset cache,可以使用iterator()方法 来获取数据,处理完数据就将其丢弃。

1

2

3

4

5

6

7

objs = Book.objects.all().iterator()

# iterator()可以一次只从数据库获取少量数据,这样可以节省内存

for obj in objs:

    print(obj.title)

#BUT,再次遍历没有打印,因为迭代器已经在上一次遍历(next)到最后一次了,没得遍历了

for obj in objs:

    print(obj.title)

当然,使用iterator()方法来防止生成cache,意味着遍历同一个queryset时会重复执行查询。所以使 #用iterator()的时候要当心,确保你的代码在操作一个大的queryset时没有重复执行查询。

总结:

queryset的cache是用于减少程序对数据库的查询,在通常的使用下会保证只有在需要的时候才会查询数据库。 使用exists()和iterator()方法可以优化程序对内存的使用。不过,由于它们并不会生成queryset cache,可能 会造成额外的数据库查询。 

中介模型

处理类似搭配 pizza 和 topping 这样简单的多对多关系时,使用标准的ManyToManyField  就可以了。但是,有时你可能需要关联数据到两个模型之间的关系上。

例如,有这样一个应用,它记录音乐家所属的音乐小组。我们可以用一个ManyToManyField 表示小组和成员之间的多对多关系。但是,有时你可能想知道更多成员关系的细节,比如成员是何时加入小组的。

对于这些情况,Django 允许你指定一个中介模型来定义多对多关系。 你可以将其他字段放在中介模型里面。源模型的ManyToManyField 字段将使用through 参数指向中介模型。对于上面的音乐小组的例子,代码如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

from django.db import models

# Create your models here.

class Person(models.Model):

    name = models.CharField(

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

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

相关文章

漫谈结构体

注意: 1.结构体是自定义数据类型,定义之后使用就跟使用库自带的int这些数据类型一样的。 2.定义结构体类型不会分配内存空间,定义变量才会。 1.匿名结构体(声明时创建变量,不然没啥用) 匿名结构体是没有定…

React 入门

一、官网地址 英文官网: https://reactjs.org/中文官网: https://react.docschina.org/ 二、React 特点 声明式编码组件化编码React Native 编写原生应用高效(优秀的 Diffing 算法)高效的原因:1.使用虚拟DOM,不总是直接操作页面…

vultr ubuntu 服务器远程桌面安装及连接

一. 概述 vultr 上开启一个linux服务器,都是以终端形式给出的,默认不带 ui 桌面的,那其实对于想使用服务器上浏览器时的情形不是很好。那有没有方法在远程服务器安装桌面,然后原程使用呢?至少ubuntu的服务器是有的&am…

搜索--找出克隆二叉树中的相同节点

题目描述 给你两棵二叉树,原始树 original 和克隆树 cloned,以及一个位于原始树 original 中的目标节点 target。 其中,克隆树 cloned 是原始树 original 的一个 副本 。 请找出在树 cloned 中,与 target 相同 的节点&#xff…

AGI时代,LLM可以在AutoML哪些环节进行增强?

当下大模型技术发展如火如荼,颇有改变各行业和各领域的架势。那么对于AutoML来讲,LLM对其有哪些助力?对于这个问题,我们来问一问kimi chat,看看它怎么回答? 大型语言模型(LLM)可以在…

React|获取oss存储的文件,并转为json格式

使用axios通过oss的url获取.xlsx文件流,处理后得到json格式数据: 安装xlsx: npm install xlsx import axios from "axios"; import * as XLSX from "xlsx";//#region xlsx(oss) to json async function getFileStream(u…

Successive Convex Approximation算法的学习笔记

文章目录 一、代码debug二、原理 本文主要参考了CSDN上的 另一篇文章,但规范了公式的推导过程和修缮了部分代码 一、代码debug 首先,我们将所有的代码放到MATLAB中,很快在命令行中出现了错误信息 很显然有问题,但是我不知道发生…

dm8用户配置免密登录

dm8用户配置免密登录 基础环境 操作系统:Red Hat Enterprise Linux Server release 7.9 (Maipo) 数据库版本:DM Database Server 64 V8 架构:单实例1 操作系统认证(sysdba) 1.1 官方文档 《DM8安全管理》手册 2 用户…

湖仓管理系统 Amoro部署

简介 Apache Amoro(incubating) 是一个构建在 Apache Iceberg 等开放数据湖表格之上的湖仓管理系统,提供了一套可插拔的数据自优化机制和管理服务,旨在为用户带来开箱即用的湖仓使用体验。 Amoro 的愿景是依托于 Apache Iceberg、Apache Paimon 等新型数据湖表格式的基础功…

Java:线程、进程、多线程

在Java中,线程、进程和多线程是实现并发编程的关键概念。理解它们的定义、特点和如何使用它们对于创建高效、响应迅速的应用程序至关重要。 进程(Process) 进程是操作系统分配资源和调度的基本单位,它包含了程序的执行状态和所需…

微信小程序媒体查询

在微信小程序中,media媒体查询不支持screen关键字,因为小程序页面是再webview中渲染的,而不是在浏览器中渲染的。 在设置样式时,可以使用 wxss 文件中的 media 规则来根据屏幕宽度或高度设置不同的样式。 device-width:设备屏幕…

redis 性能管理

一、查看 redis 内存使用 info memory 1, 进入 redis 查看 2, redis 外查看 二 内存碎片率 1,used_memory_rss 表示该进程所占物理内存的大小,即为操作系统分配给 Redis 实例的内存大小。 2,used_memory Redis …

手机领域的平台之战

平台应用的模式最早是从手机应用开始的。在管理软件领域,最早是各厂商自己做自己的App。OA厂商、CRM厂商、HR厂商等等,都推自己的APP。现在逐步放弃了自有App,转向小程序。也就是平台之战第一阶段结束,几个大厂干掉了千千万万个小…

git如何正确合并分支

在 Git 中,合并分支是一个常见的操作,它允许你将一个分支的更改集成到另一个分支中。以下是一些正确合并分支的步骤和最佳实践: 合并前需要add和commit -m 提交到本地仓库在进行合并 1. 查看分支状态 在合并之前,最好先查看当前仓…

【智能算法】猎豹优化器(CO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献 1.背景 2022年,MA Akbari等人受到自然界中猎豹捕猎行为启发,提出了猎豹优化器(The Cheetah Optimizer,CO)。 2.算法原理 2.1算法思想 CO法对猎…

机器学习的模型校准

背景知识 之前一直没了解过模型校准是什么东西,最近上班业务需要看了一下: 模型校准是指对分类模型进行修正以提高其概率预测的准确性。在分类模型中,预测结果通常以类别标签形式呈现(例如,0或1)&#xf…

Python程序设计 单例模式

1. 单例设计模式 设计模式设计模式 是 前人工作的总结和提炼,通常,被人们广泛流传的设计模式都是针对 某一特定问题 的成熟的解决方案使用 设计模式 是为了可重用代码、让代码更容易被他人理解、保证代码可靠性单例设计模式目的 —— 让 类 创建的对象&…

mac 上通过命令行挂载NTFS硬盘,使其可以进行读写

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言1. 安装 osxfuse 和 ntfs-3g2. 挂载 NTFS 硬盘3. 卸载 NTFS 硬盘4. 自动挂载1. 找出设备UUID2. 编辑 /etc/fstab 文件3. 添加挂载信息4. 保存并退出编辑器5. 重…

【THM】Nmap Advanced Port Scans(高级端口扫描)-初级渗透测试

介绍 本房间是Nmap系列的第三个房间(网络安全简介模块的一部分)。在前两个房间中,我们了解了实时主机发现和基本端口扫描。 Nmap实时主机发现Nmap基本端口扫描Nmap高级端口扫描Nmap后端口扫描在Nmap基本端口扫描中,我们介绍了TCP标志并回顾了TCP 3 路握手。要启动连接,TC…

AcWing刷题-约数个数

约数的个数 代码 # 计数 def f(x)->int:cnt 0i 1while i * i < x:if x % i 0:cnt 1if i * i < x:cnt 1i 1return cntn int(input()) a list(map(int,input().split())) for i in a:print(f(i))