第一期:通过Django创建数据库约束
一)
django 似乎还没有内置这种能力。有一个 9 岁的开放ticket,但我不会为已经发生这么长时间的事情屏住呼吸。
编辑:从 2.2 版(2019 年 4 月)开始,Django 支持数据库级 check constraints。
B) 您可以查看包django-db-constraints,通过它您可以在模型Meta 中定义约束。我没有测试这个包,所以我不知道它到底有多大用处。
# example using this package
class Meta:
db_constraints = {
'price_above_zero': 'check (price > 0)',
}
第二个问题:字段system不应为空,也不应包含空格
现在我们需要在postgres 语法中构建check 约束来完成它。我想出了这些选项:
-
检查删除空格后system 的长度是否不同。使用this answer 的想法,您可以尝试:
/* this check should only pass if `system` contains no
* whitespaces (`\s` also detects new lines)
*/
check ( length(system) = length(regexp_replace(system, '\s', '', 'g')) )
-
检查空白计数是否为 0。为此,您可以联系我们 regexp_matches:
/* this check should only pass if `system` contains no
* whitespaces (`\s` also detects new lines)
*/
check ( length(regexp_matches(system, '\s', 'g')) = 0 )
请注意,length 函数不能与 regexp_matches 一起使用,因为后者返回 set of text[](数组集),但我找不到合适的函数来计数现在该集合的元素。
最后,将前两个问题结合起来,您的方法可能如下所示:
class Dummy(models.Model):
# this already sets NOT NULL to the field in the database
system = models.CharField(max_length=16)
class Meta:
db_constraints = {
'system_no_spaces': 'check ( length(system) > 0 AND length(system) = length(regexp_replace(system, "\s", "", "g")) )',
}
这会检查字段值:
- 不包含NULL(
CharField默认添加NOT NULL约束)
- 不为空(
check的第一部分:length(system) > 0)
- 没有空格(
check 的第二部分:替换空格后长度相同)
让我知道这对您有何影响,或者这种方法是否存在问题或缺点。