Można to zrobić w nadpisanej metodzie save
. Należy pamiętać, że instancje modelu Django nie są rzeczywistymi obiektami bazy danych, po prostu pobierają swoje wartości z obciążenia. Możesz więc łatwo wrócić do bazy danych przed zapisaniem bieżącego obiektu, aby uzyskać istniejące wartości.
def save(self, *args, **kwargs):
if self.status == 'pending':
old_instance = MyClass.objects.get(pk=self.pk)
if old_instance.status == 'activated':
raise SomeError
super(MyModel, self).save(*args, **kwargs)
Obecnie nie ma dobrego sposobu na zwrócenie użytkownikowi błędu innego niż zgłoszenie wyjątku. Obecnie trwa projekt Google Summer of Code, który umożliwia "walidację modelu", ale nie będzie on gotowy przez kilka miesięcy.
Jeśli chcesz zrobić coś podobnego w admin, najlepszym sposobem jest zdefiniowanie niestandardowego ModelForm z przesłoniętą metodą clean()
. Jednak tym razem, ponieważ jest to formularz, masz już dostęp do starych wartości bez ponownego uderzania w db. Kolejną korzyścią jest to, że użytkownik może zwrócić błąd sprawdzania poprawności formularza.
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
def clean_status(self):
status = self.cleaned_data.get('status', '')
if status == 'pending':
if self.instance and self.instance.status == 'activated':
raise forms.ValidationError(
'You cannot change activated to pending'
)
return status
class MyModelAdmin(forms.ModelAdmin):
form = MyModelForm
model = MyModel
+1 - Zastanawiam się nad tym samym.W moim przypadku jest ciężka praca, która jest wykonywana w metodzie zapisu, która jest konieczna tylko wtedy, gdy zmieniło się pole w konkretnym podzbiorze pól modelu i szukałem sposobu na sprawdzenie, czy tak jest, czy nie. . Dzięki! –