如何在Django中实现含lower()函数的music表查询?
在Django中执行含LOWER()函数的SQL查询
你提到想用Django实现SELECT * FROM music where lower(music.name) = "hello"这样的查询,但name__iexact生成的是带LIKE的SQL——这是因为Django的iexact是依赖数据库的大小写不敏感规则来实现的(比如MySQL的_ci排序规则),并不是强制用LOWER()函数。
如果一定要生成包含LOWER()函数的SQL,有几种靠谱的方法:
方法一:使用Django的Lower数据库函数(推荐)
这是最符合Django ORM风格的方式,既安全又能生成你想要的SQL:
首先导入Lower函数:
from django.db.models.functions import Lower
然后执行查询:
Music.objects.annotate(lower_name=Lower('name')).filter(lower_name='hello')
这个查询会生成类似这样的SQL:
SELECT `music`.`id`, `music`.`name`, ..., LOWER(`music`.`name`) AS `lower_name` FROM `music` WHERE LOWER(`music`.`name`) = 'hello' LIMIT 21
完美匹配你想要的逻辑,而且返回的是QuerySet,可以继续链式调用其他ORM方法。
方法二:使用extra方法(兼容旧版本Django)
如果你的Django版本比较旧,可以用extra直接指定原生WHERE条件(注意:extra在Django 3.2+已被标记为废弃,优先用方法一):
Music.objects.extra(where=['lower(music.name) = %s'], params=['hello'])
这里用params传参是为了避免SQL注入,不要直接把字符串拼进去。
方法三:原生SQL查询
如果完全需要自定义SQL,可以直接用Django的数据库连接执行:
from django.db import connection with connection.cursor() as cursor: cursor.execute("SELECT * FROM music where lower(music.name) = %s", ['hello']) rows = cursor.fetchall()
不过这种方式返回的是原始的元组数据,不是Music模型实例,适合不需要ORM特性的场景。
内容的提问来源于stack exchange,提问作者Arian
相关产品推荐
相关产品推荐

