关于Django以前忽略的一些东西
Django直接使用sql查询
官方文档:执行原生 SQL 查询 | Django 文档 | Django (djangoproject.com)
将查询字段映射为模型字段¶
raw()
字段将查询语句中的字段映射至模型中的字段。
查询语句中的字段排序并不重要。换而言之,以下两种查询是一致的:
1 | 'SELECT id, first_name, last_name, birth_date FROM myapp_person') Person.objects.raw( |
直接执行自定义 SQL¶
有时候,甚至 Manager.raw()
都无法满足需求:你可能要执行不明确映射至模型的查询语句,或者就是直接执行 UPDATE
, INSERT
或 DELETE
语句。
这些情况下,你总是能直接访问数据库,完全绕过模型层。
对象 django.db.connection
代表默认数据库连接。要使用这个数据库连接,调用 connection.cursor()
来获取一个指针对象。然后,调用 cursor.execute(sql, [params])
来执行该 SQL 和 cursor.fetchone()
,或 cursor.fetchall()
获取结果数据。
例如:
1 | from django.db import connection |
要避免 SQL 注入,你绝对不能在 SQL 字符串中用引号包裹 %s
占位符。
注意,若要在查询中包含文本的百分号,你需要在传入参数使用两个百分号:
1 | cursor.execute("SELECT foo FROM bar WHERE baz = '30%'") |
若你同时使用 不止一个数据库,你可以使用 django.db.connections
获取指定数据库的连接(和指针)。 django.db.connections
是一个类字典对象,它允许你通过连接别名获取指定连接:
1 | from django.db import connections |
Queryset的缓存行为
Queryset是有缓存的,但也不是一直都缓存,得遍历过一遍之后才会有缓存。
官方文档:执行查询 | Django 文档 | Django (djangoproject.com)
当 QuerySet
未被缓存时¶
查询结果集并不总是缓存结果。当仅计算查询结果集的 部分 时,会校验缓存,若没有填充缓存,则后续查询返回的项目不会被缓存。特别地说,这意味着使用数组切片或索引的 限制查询结果集 不会填充缓存。
例如,重复的从某个查询结果集对象中取指定索引的对象会每次都查询数据库:
1 | all() queryset = Entry.objects. |
不过,若全部查询结果集已被检出,就会去检查缓存:
1 | all() queryset = Entry.objects. |