一、raw()方法基础与典型问题场景
Django的raw()方法允许开发者直接执行原生SQL查询,返回模型实例集合。其基本语法为:
Book.objects.raw('SELECT * FROM library_book WHERE publication_date > %s', [date])
在实际使用中,开发者常遇到以下核心问题:结果集字段映射错误。当SQL查询返回的列名与模型字段不匹配时,会导致属性访问异常。例如:
- SQL使用
AS别名时未与模型字段对应 - JOIN查询返回重复列名未显式指定
- 聚合函数结果未正确映射
二、参数化查询与SQL注入防御
使用raw()时最大的安全隐患是SQL注入漏洞。以下为错误示范:
# 危险!直接拼接字符串 query = "SELECT * FROM auth_user WHERE username = '%s'" % request.GET['user'] User.objects.raw(query)
正确做法应使用参数化查询:
- 使用
%s占位符(PostgreSQL用%s,SQLite用?) - 通过第二个参数传递值列表
- 对动态表名使用
.extra()而非字符串拼接
三、高级映射与性能优化
复杂查询时可通过以下方式优化:
| 场景 | 解决方案 |
|---|---|
| 跨模型字段映射 | 使用translations参数指定字段别名 |
| 自定义结果处理 | 重写prefetch_related或定义@property |
| 大批量数据 | 结合iterator()流式处理 |
四、调试与异常处理
当查询出错时,Django会抛出django.db.utils.DatabaseError。建议:
- 使用
connection.queries查看最终执行的SQL - 捕获
DataError处理类型转换异常 - 对复杂查询先使用数据库客户端验证语法
典型调试流程示例:
from django.db import connection
try:
results = Book.objects.raw(complex_query)
[print(row) for row in results]
finally:
print(connection.queries[-1]['sql'])