Вы можете сделать это переопределенным методом save
. Следует помнить, что экземпляры модели Django не являются реальными объектами базы данных, они просто получают свои значения оттуда при загрузке. Таким образом, вы можете легко вернуться к базе данных перед сохранением текущего объекта, чтобы получить существующие значения.
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)
В настоящее время нет другого способа вернуть пользователю сообщение об ошибке, кроме как вызвать исключение. В настоящее время реализуется проект Google Summer of Code, позволяющий включить проверку модели, но он не будет готов в течение нескольких месяцев.
Если вы хотите сделать что-то подобное в админке, лучше всего определить пользовательскую ModelForm с переопределенным методом clean()
. Однако на этот раз, так как это форма, у вас уже есть доступ к старым значениям без повторного нажатия на базу данных. Еще одним преимуществом является то, что вы можете вернуть пользователю ошибку проверки формы.
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