在Sqlite3中(使用Django)可以实现不区分大小写的'唯一'约束吗?
假设我在用Python 2.5自带的sqlite3,并且我有一个Django模型类,代码如下:
class SomeEntity(models.Model):
some_field = models.CharField(max_length=50, db_index=True, unique=True)
我已经设置好了管理界面,所有功能看起来都正常,但我可以创建两个SomeEntity记录,一个是some_field='some value',另一个是some_field='Some Value',因为some_field的唯一性约束似乎是区分大小写的。
有没有办法让sqlite在检查唯一性时忽略大小写进行比较呢?
我在Django的文档中找不到这个选项,我在想有没有什么方法可以直接对sqlite进行设置,让它按照我想要的方式工作。:-)
3 个回答
2
对于2021年的人来说,借助于 Django 4.0 的 UniqueConstraint 表达式,你可以像下面这样在你的模型中添加一个 Meta 类:
class Meta:
constraints = [
models.UniqueConstraint(
Lower('<field name>'),
name='<constraint name>'
),
]
4
也许你可以创建一个自定义的模型字段;这个字段可以是CharField的一个子类,但需要提供一个叫做 db_type 的方法,这个方法返回“text collate nocase”。
11
是的,这个可以很简单地通过给表添加一个唯一索引来实现,使用下面的命令:
CREATE UNIQUE INDEX uidxName ON mytable (myfield COLLATE NOCASE)
如果你需要对非ASCII字符(比如中文、日文等)进行不区分大小写的处理,你需要注册你自己的排序规则,命令类似于下面这样:
下面的例子展示了一个自定义的排序规则,它的排序方式是“反向的”:
import sqlite3
def collate_reverse(string1, string2):
return -cmp(string1, string2)
con = sqlite3.connect(":memory:")
con.create_collation("reverse", collate_reverse)
cur = con.cursor()
cur.execute("create table test(x)")
cur.executemany("insert into test(x) values (?)", [("a",), ("b",)])
cur.execute("select x from test order by x collate reverse")
for row in cur:
print row
con.close()
关于sqlite3的更多Python文档可以在 这里 找到