[英]Django: Foreign key optional but unique?
我有一個具有2個外鍵的模型( A
): b
和c
。
b
和c
應該一起唯一, 包括NULL
因此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 |
+----+------+------+
前2行只能由django插入一次。 太好了 :)
但是,剩余的行對我來說是重復的條目,我想對此進行限制。
UPDATE
我發現可以完成工作的東西,但看起來確實很hack ..有什么想法嗎?
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")
也許有更好的解決方案,但是您可以執行以下操作:
d
並找到一種組合b_id
和c_id
的通用方法(例如str(b_id) + "*" + str(c_id)
,並在模型創建時自動執行(信號機制可能會派上用場) d
作為primary_key 這是更多的解決方案,而不是解決方案,但是應該可以解決問題。
再想一想:是否可以選擇在創建/更新實例時檢查現有實例是否帶有“ Null” /“ Null”? 這不會在數據庫級別解決您的問題,但是邏輯將按預期工作。
這不是Django的問題,而是SQL規范本身的問題-NULL不是值,因此唯一性約束檢查不得將其考慮在內。
您可以在數據庫中擁有一個“偽空” B記錄和一個“偽空” C記錄,並將它們設置為默認值(當然不允許NULL),或者可以像OBu建議的那樣使用非規范化字段。
您可以對b_id列使用“ 唯一性”約束。 它不允許重復的條目 。 即使對於a_id列,也可以使用主鍵 。 主鍵是指唯一鍵和非空約束的組合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.