Django 中不区分大小写的唯一模型字段?

新手上路,请多包涵

我基本上有一个用户名是唯一的(不区分大小写),但在显示用户提供的时,大小写很重要。

我有以下要求:

  • 字段与 CharField 兼容
  • 字段是唯一的,但不区分大小写
  • 字段需要忽略大小写可搜索(避免使用 iexact,容易忘记)
  • 字段存储时大小写完好
  • 最好在数据库级别执行
  • 最好避免存储额外的字段

这在 Django 中可能吗?

我想出的唯一解决方案是“以某种方式”覆盖模型管理器、使用额外字段或始终在搜索中使用“iexact”。

我在 Django 1.3 和 PostgreSQL 8.4.2 上。

原文由 noobzie 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 898
2 个回答

将原始 混合大小写字符串存储在纯文本列 中。使用不带长度修饰符的数据类型 textvarchar 而不是 varchar(n) 。它们本质上是相同的,但是对于 varchar(n) ,您必须设置任意长度限制,如果您以后想更改,这可能会很痛苦。 在手册Peter Eisentraut @serverfault.SE 的相关回答 中阅读更多相关信息。

lower(string) 上创建 功能唯一索引。这是这里的重点:

 CREATE UNIQUE INDEX my_idx ON mytbl(lower(name));

如果您尝试 INSERT 一个已经存在的小写混合名称,您会收到唯一的密钥违规错误。

对于快速相等搜索,使用这样的查询:

 SELECT * FROM mytbl WHERE lower(name) = 'foo' --'foo' is lower case, of course.

使用与索引中相同的表达式(以便查询规划器识别兼容性),这将非常快。


顺便说一句:您可能想要升级到更新版本的 PostgreSQL。 自 8.4.2 以来有很多重要的修复。更多关于 官方 Postgres 版本控制站点

原文由 Erwin Brandstetter 发布,翻译遵循 CC BY-SA 3.0 许可协议

从 Django 1.11 开始,您可以使用 CITextField ,这是一个 Postgres 特定的字段,用于由 citext 类型支持的不区分大小写的文本。

 from django.db import models
from django.contrib.postgres.fields import CITextField

class Something(models.Model):
    foo = CITextField()

Django also provides CIEmailField and CICharField , which are case-insensitive versions of EmailField and CharField .

原文由 Rodney Folz 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题