我有一個開始和結束日期範圍的Django模型。我想執行驗證,以便沒有兩個記錄具有重疊的日期範圍。什麼是最簡單的方式來實現這一點,以便我不必重複自己寫這種邏輯?添加自定義Django模型驗證
例如我不想以表格和 a ModelForm
和管理員表格和重新實現此邏輯,該模型的覆蓋save()
。
據我所知,Django並不容易全球執行這些類型的標準。
谷歌搜索並沒有太大的幫助,因爲「模型驗證」通常是指驗證特定的模型字段,而不是整個模型內容或字段之間的關係。
我有一個開始和結束日期範圍的Django模型。我想執行驗證,以便沒有兩個記錄具有重疊的日期範圍。什麼是最簡單的方式來實現這一點,以便我不必重複自己寫這種邏輯?添加自定義Django模型驗證
例如我不想以表格和 a ModelForm
和管理員表格和重新實現此邏輯,該模型的覆蓋save()
。
據我所知,Django並不容易全球執行這些類型的標準。
谷歌搜索並沒有太大的幫助,因爲「模型驗證」通常是指驗證特定的模型字段,而不是整個模型內容或字段之間的關係。
我發現有用的基本模式是把我所有的自定義驗證在clean()
,然後簡單地調用full_clean()
(它調用clean()
和一些其他方法)從裏面save()
,如:
class BaseModel(models.Model):
def clean(self, *args, **kwargs):
# add custom validation here
super(BaseModel, self).clean(*args, **kwargs)
def save(self, *args, **kwargs):
self.full_clean()
super(BaseModel, self).save(*args, **kwargs)
這如here所解釋的,因爲它會干擾某些功能,但這些對我的應用程序來說不是問題。
我認爲你應該使用這樣的: https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects
就在你的模型是這樣定義清潔()方法:(例如,從文檔鏈接)
def clean(self):
from django.core.exceptions import ValidationError
# Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None:
raise ValidationError('Draft entries may not have a publication date.')
# Set the pub_date for published items if it hasn't been set already.
if self.status == 'published' and self.pub_date is None:
self.pub_date = datetime.datetime.now()
我將在覆蓋validate_unique
方法該模型。爲了確保您忽略驗證時,當前的對象,你可以使用以下命令:
from django.db.models import Model, DateTimeField
from django.core.validators import NON_FIELD_ERRORS, ValidationError
class MyModel(Model):
start_date = DateTimeField()
end_date = DateTimeField()
def validate_unique(self, *args, **kwargs):
super(MyModel, self).validate_unique(*args, **kwargs)
qs = self.__class__._default_manager.filter(
start_date__lt=self.end_date,
end_date__gt=self.start_date
)
if not self._state.adding and self.pk is not None:
qs = qs.exclude(pk=self.pk)
if qs.exists():
raise ValidationError({
NON_FIELD_ERRORS: ['overlapping date range',],
})
ModelForm
會自動通過full_clean()
,您可以手動使用過調用此爲您服務。
PPR對簡單,正確的range overlap condition進行了很好的討論。
在django 1.3.1上,我遇到了一個以你描述它的方式引發ValidationError的問題。我可以通過在引發異常時傳遞{field:(error_msg,)}字典而不是字符串error_msg來解決此問題。 – adam
'從django.core.exceptions進口ValidationError,NON_FIELD_ERRORS' '提高ValidationError({NON_FIELD_ERRORS:( '重疊的日期範圍')})' – adam
是否有延長'validate_unique',而不是僅僅定義'clean'任何權益?只是組織代碼的問題? – lajarre
這就近了。我也必須重寫模型的save(),並從那裏調用clean()。 – Cerin
但是什麼? AdminSite(ModelForm)自動調用clean()。但是從save()方法調用clean()可能會在意想不到的時刻產生ValidationError,並且不會像預期的那樣發生。 – alTus
並非所有的東西都叫乾淨。無論保存的位置如何,都需要進行驗證。破損的網站頁面可能會損壞數據。 – Cerin