【问题标题】:Force django admin search bar to be case insensitive强制 django 管理搜索栏不区分大小写
【发布时间】:2018-08-21 15:53:59
【问题描述】:

我的问题是,对于我的一个模型,相应管理页面的搜索栏正在执行一个大小写 sensitive 搜索,而它应该是一个大小写 insensitive 搜索默认。

从我能找到的 here 来看,我觉得这可能与数据库编码有关,但从 the doc 来看,它说 Django 假定所有内容都是 UTF-8 编码的,我检查了我的 MySQL 表和字段以 UTF-8 编码。

可能是因为我的某个领域中存在希腊字符吗?如何在至少不包含希腊字母的字段中强制进行不区分大小写的搜索?目前,搜索对所有字段都区分大小写。但它适用于其他模型(不区分大小写)。

型号:

class MyModel(models.Model):
    id = models.AutoField(primary_key=True)
    field1 = models.CharField(max_length=200) # Might contain greek letters
    field2 = models.CharField(max_length=200, unique=True)

不共享管理类代码,因为这里没有什么花哨的东西。只是list_display、search_fields、ordering 和fieldsets 的标准组合。

使用 Django 1.10

编辑
这是相关表的SHOW CREATE TABLE 的输出:

CREATE TABLE `my_model` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `field1` varchar(200) COLLATE utf8_bin NOT NULL,
    `field2` varchar(200) COLLATE utf8_bin NOT NULL,
    # Non relevant other fields
    PRIMARY KEY (`id`),
    UNIQUE KEY `my_model_field2_63f9df5e_uniq` (`field2`)
) ENGINE=InnoDB AUTO_INCREMENT=657 DEFAULT CHARSET=utf8 COLLATE=utf8_bin

现在我看到了,这可能是由于_bin 对吧?我应该转换成带有_ci 的东西吗?在 Django 中这样做的方式是什么?

【问题讨论】:

标签: mysql django django-models encoding character-encoding


【解决方案1】:

utf8_bin 区分大小写。更改为utf8_unicode_520_ci(如果使用 MySQL 5.6 或 5.7):

ALTER TABLE my_model CONVERT TO COLLATION utf8_unicode_520_ci;

使用LOWER() 可能有效,但速度很慢,因为它会阻止使用索引,从而可能使查询运行速度比实际运行速度慢很多。

注意:要允许表情符号和所有中文,需要utf8mb4 代替utf8。

您的模型为单个表指定了 3 个唯一键?这似乎太过分了。然后我被 CREATE TABLE 弄糊涂了——它只显示了 2 个。(注意:PRIMARY KEY 是 UNIQUE。)

根据Django docs“在所有情况下,您都可以通过直接操作数据库表来设置排序规则;Django 没有提供在模型定义上设置它的方法。”正如 OP 所展示的,通过 MySQL 实用程序使用 SHOW CREATE TABLE 可以告诉您当前正在使用什么排序规则。

【讨论】:

  • 谢谢 我现在明白如果我使用utf8_whatever_ci 它可能会解决我的问题。我想知道是否有 Django 方法可以做到这一点?
  • 您能否编辑您的答案以指定“Django 不支持通过 ORM 进行排序操作的任何方式。” (这是我正在寻找的另外 50% 的答案)所以我可以接受你的答案吗? See this part of the doc。 field1 也不是唯一的,我编辑了我的问题。
  • @Cyrlop - 是的,该文档对排序规则有非常具体的说明。我修改了大部分答案。
【解决方案2】:
from django.db.models.functions import Lower
qs = MyModel.objects.annotate(field1_lower=Lower('field1')) # annotate each item in the queryset with the code_lower

现在使用 field1_lower 而不是 field1 进行搜索。希望对您有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-15
    • 2013-09-26
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 1970-01-01
    • 2021-11-27
    相关资源
    最近更新 更多