2015-08-20 60 views
0

我有一個Django模型是這樣的:Django的唯一性約束在特定領域爲True

class Process(Place): 
    isRunning = models.BooleanField(default=True) 
    name  = models.CharField(max_length=20) 

我想執行的name域是唯一的,當isRunning是真實的。

這個約束在Django模型中可能嗎?


這可能是 this question的重複,但它沒有被接受的答案,並且自從它被問到時,Django開發了很多。

+0

你可以指定['unique_together'字段](https://docs.djangoproject.com/en/1.8/ref/models/options/#unique-together),但是這也會強制「name」是唯一的記錄'isRunning'是'false'(即你有兩組唯一的名字)...否則你可以自定義[模型驗證](https://docs.djangoproject.com/en/1.8/ref/models/儘管記住它只是在保存ModelForm和Django admin時自動調用,而不是當執行'instance.save()' – Anentropic

回答

1

唯一字段意味着在該字段的數據庫中構建唯一索引。

現在,由於您的字段依賴於來自同一模型的字段,因此您可以選擇在模型保存時驗證此字段。如果你的數據庫支持它,你可以建立一個partial unique index

def save(self, *args, **kwargs): 
    #check if isRunning is true or not  
    super(Model, self).save(*args, **kwargs) 
+1

這很好,很簡單。我寧願讓自己的鼻子遠離SQL,所以我會走這條路。 – ajwood

+0

upvote會很好:D –

+1

@ajwood:請注意,如果您依賴於重寫'save()',那麼您將被限制於那些使用它的方法。特別是,你將無法使用'.update()'和'.bulk_create()'。在數據庫中擁有約束的好處是,無論如何,你知道它將被執行。 –

0

您可以覆蓋模型保存喜歡()方法。

部分索引是構建在表的子集上的索引;該子集由一個條件表達式(稱爲部分索引的謂詞)定義。該索引僅包含滿足謂詞的那些錶行的條目。

沒有特殊的Django支持,但您可以在數據遷移中進行設置(有關更多詳細信息,請參閱here)。

在你的情況下,它看起來是這樣的:

operations = [ 
    migrations.RunSQL("CREATE UNIQUE INDEX running_name ON app_process(isRunning, name) 
         WHERE isRunning"), 
] 
0

您可以添加一個額外的領域,如stopped_at錄製過程被殺害的時間。

,並創建一個唯一約束:

unique_together = ('name', 'stopped_at') 

stopped_at可以設置爲無或新進程的一些恆定值。

該約束將確保名稱在正在運行的進程中是唯一的。並且停止的進程可以具有相同的名稱,因爲它們的stops_at總是不同的(希望或者您可以將其他信息添加到這個棘手的字段以保證停止進程的唯一性)。