我在Django Model中有一个字段用于存储唯一(哈希)值。事实证明,数据库(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 )
我可以更改'哈希字段'到二进制字段,所以在数据库中它变成了一个LONGBLOB,并且它确实进行了区分大小写的搜索(并且有效)。但是,这对我来说似乎并不高效。 是否有更好的方法(在Django中)这样做,例如添加&ut; utf8 COLLATE'?或者在这种情况下什么是正确的Fieldtype? (是的,我知道我可以使用PostgreSQL代替..)
答案 0 :(得分:3)
MySQL字符集的默认排序规则是latin1_swedish_ci,它不区分大小写。不知道为什么会这样。但您应该像这样创建数据库:
CREATE DATABASE database_name CHARACTER SET utf8;
答案 1 :(得分:2)
正如@ dan-klasson所提到的,default non-binary string comparison is case insensetive by default;注意_ci
末尾的latin1_swedish_ci
,它代表案例介绍。
正如Dan所提到的,您可以使用区分大小写的排序规则和字符集创建数据库。
您可能也有兴趣知道您可以随时create a single table or even set only a single column to use a different collation(同样的结果)。您也可以在创建后更改这些排序规则,例如每个表:
ALTER TABLE documents__document CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
此外,如果您不想更改数据库/表格charset / collation,Django允许run a custom query using the raw method。因此,您可以通过使用以下内容来解决此问题,但我自己没有对此进行过测试:
Document.objects.raw("SELECT * FROM documents__document LIKE '%s' COLLATE latin1_bin", ['abcd123'])
答案 2 :(得分:0)
您的区分大小写的过滤器查询错误。它应该是__exact
,如下所示:
Document.objects.get(hash__exact="abcd123")
对于不区分大小写的过滤器查询,您需要使用__iexact
。