Django 中区分大小写的搜索,但在 Mysql 中被忽略

Case sensitive search in Django, but ignored in Mysql

我在 Django 模型中有一个字段用于存储唯一(哈希)值。事实证明,数据库 (MySQL/inno) 不会对这种类型 (VARCHAR) 进行区分大小写的搜索,即使我明确告诉 Django 进行区分大小写的搜索 Document.objects.get(hash__exact="abcd123") 也是如此。所以 "abcd123" 和 "ABcd123" 都被返回,这是我不想要的。

class document(models.Model):
   filename    = models.CharField(max_length=120)
   hash        = models.CharField(max_length=33 )

我可以将 'hash field' 更改为 BinaryField ,因此在数据库中它变成了 LONGBLOB ,并且它确实进行区分大小写的搜索(并且有效)。但是,这对我来说似乎不是很有效。 有没有更好的方法(在 Django 中)来做到这一点,比如添加 'utf8 COLLATE'?或者在这种情况下正确的 Fieldtype 是什么? (是的,我知道我可以改用 PostgreSQL..)

MySQL 字符集的默认排序规则是 latin1_swedish_ci,不区分大小写。不知道为什么会这样。但是你应该像这样创建你的数据库:

CREATE DATABASE database_name CHARACTER SET utf8;

正如@dan-klasson 提到的,default non-binary string comparison is case insensetive by default;注意 latin1_swedish_ci 末尾的 _ci,它代表不区分大小写。 正如 Dan 所提到的,您可以使用区分大小写的排序规则和字符集创建数据库。

您可能还想知道您始终可以 create a single table or even set only a single column to use a different collation(获得相同的结果)。您还可以更改这些排序规则 post 创建,例如每个 table:

ALTER TABLE documents__document CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

此外,如果您不想更改 database/table charset/collation,Django 允许 run a custom query using the raw method。所以你可以通过使用类似下面的东西来解决这个变化,虽然我自己没有测试过:

Document.objects.raw("SELECT * FROM documents__document LIKE '%s' COLLATE latin1_bin", ['abcd123'])