我的模型(A
)有2个外键:b
和c
。
b
和c
应该是唯一的包含空
因此b
和c
一起只能为NULL ONCE
但是,我无法在Django中完成此任务。这是我到目前为止的代码。任何帮助表示赞赏!
-_-
class A(models.Model):
b = models.ForeignKey('B', blank = True, null = True)
c = models.ForeignKey('C', blank = True, null = True)
class Meta:
unique_together = (
('b', 'c')
)
此代码将在数据库中生成此不需要的结果:
+----+------+------+
| id | b_id | c_id |
+----+------+------+
| 1 | 2 | 3 |
| 2 | 2 | 77 |
| 3 | 2 | NULL |
| 4 | 2 | NULL |
| 5 | NULL | NULL |
| 6 | NULL | NULL |
+----+------+------+
前两行只能由django插入一次。 很棒:)
但是,剩余的行对我来说是重复的条目,我想限制它。
更新
我找到了可以完成工作的东西,但它看起来真的很糟糕...... 有什么想法吗?
class A(models.Model):
def clean(self):
from django.core.exceptions import ValidationError
if not any([self.b, self.c]):
if Setting.objects.filter(b__isnull = True, c__isnull = True).exists():
raise ValidationError("Already exists")
elif self.b and not self.c:
if Setting.objects.filter(c__isnull = True, b = self.b).exists():
raise ValidationError("Already exists")
elif self.c and not self.user:
if Setting.objects.filter(c = self.c, b__isnull = True).exists():
raise ValidationError("Already exists")
答案 0 :(得分:1)
也许有更好的解决方案,但你可以做到以下几点:
d
并找到合并b_id
和c_id
的通用方法(例如str(b_id) + "*" + str(c_id)
,并在模型创建时自动执行此操作(信号机制可能会出现)方便,在这里)d
作为primary_key 这更像是一个解决方案,但它应该可以解决问题。
还有一个想法:在创建/更新实例时,是否可以检查是否存在“Null”/“Null”的现有实例?这不会解决您在数据库级别上的问题,但逻辑将按预期工作。
答案 1 :(得分:1)
这不是Django的问题,但是对于SQL规范本身 - NULL不是值,因此不能将其考虑在唯一性约束检查中。
你可以在你的数据库中有一个“伪空”B记录和一个“伪空”C记录,并使它们成为默认值(当然不允许NULL),或者像OBu建议的那样具有非规范化字段。
答案 2 :(得分:-1)
您可以对 b_id 列使用唯一约束。它不允许重复条目。即使对于a_id列,也可以使用主键。主键表示唯一键和非空约束的组合。