Django __exact查询集过滤器大小写敏感失效,求问题排查
问题原因与解决办法
这个问题其实是**数据库排序规则(collation)**在搞鬼!虽然Django文档里说__exact是大小写敏感的,但这个行为最终取决于你的数据库字段使用的排序规则——如果字段用的是大小写不敏感的规则(比如MySQL常用的utf8_general_ci),数据库会把"d"和"D"判定为相等,自然就返回了两条数据。
下面给你两种可行的解决思路:
1. 修改字段的数据库排序规则(推荐长期方案)
直接在Django模型里给name字段指定大小写敏感的排序规则,比如utf8mb4_bin(比utf8_bin更适合现代场景,支持emoji等全字符):
class MyObject(models.Model): name = models.CharField(max_length=255, db_collation='utf8mb4_bin')
然后执行数据库迁移命令:
python manage.py makemigrations python manage.py migrate
这样之后,__exact就会严格区分大小写了。
2. 不修改数据库结构,在查询时强制二进制比较
如果暂时不想改数据库,可以用Django的Func函数生成二进制比较的SQL,绕过排序规则的影响:
from django.db.models import Func, F # 直接在过滤时转成二进制匹配 lower_case_test = MyObject.objects.filter( Func(F('name'), function='BINARY') == "d" )
或者先通过annotate生成二进制字段再过滤:
lower_case_test = MyObject.objects.annotate( binary_name=Func(F('name'), function='BINARY') ).filter(binary_name=b"d") # 注意这里用字节串b"d"
简单总结:Django的__exact本身是遵循“数据库层面的精确匹配”,而数据库是否区分大小写完全由字段的排序规则决定,这就是你没得到预期结果的核心原因~
内容的提问来源于stack exchange,提问作者dev_py_uk
相关产品推荐
相关产品推荐

