У меня есть модель заказа, которая должна проверить, доступен ли выписанный объект. Я хотел бы иметь логику позади выяснения, если объект доступен централизованный так, чтобы, неважно, где я сохраняю экземпляр, этот код проверил это, это может быть сохранено.
В данный момент у меня есть этот код в пользовательской функции сохранения моего образцового класса:
def save(self):
if self.is_available(): # my custom check availability function
super(MyObj, self).save()
else:
# this is the bit I'm stuck with..
raise forms.ValidationError('Item already booked for those dates')
Это хорошо работает - ошибка повышена, если объект недоступен, и мой объект не сохраняется. Я могу получить исключение из своего кода формы фронтэнда, но что относительно администраторского сайта Django? Как я могу заставить свое исключение быть отображенным как какая-либо другая ошибка проверки в администраторском сайте?
Я также попытался решить эту проблему, и есть мое решение - в моем случае мне нужно было отклонить любые изменения в связанных_объектах, если основной_объект заблокирован для редактирования.
1) настраиваемое исключение
class Error(Exception):
"""Base class for errors in this module."""
pass
class EditNotAllowedError(Error):
def __init__(self, msg):
Exception.__init__(self, msg)
2) метакласс с настраиваемым методом сохранения - все мои модели related_data будут основаны на этом:
class RelatedModel(models.Model):
main_object = models.ForeignKey("Main")
class Meta:
abstract = True
def save(self, *args, **kwargs):
if self.main_object.is_editable():
super(RelatedModel, self).save(*args, **kwargs)
else:
raise EditNotAllowedError, "Closed for editing"
3) метаформа - все мои административные формы related_data будут основаны на этом (это будет гарантировать, что Интерфейс администратора проинформирует пользователя без ошибок интерфейса администратора):
from django.forms import ModelForm, ValidationError
...
class RelatedModelForm(ModelForm):
def clean(self):
cleaned_data = self.cleaned_data
if not cleaned_data.get("main_object")
raise ValidationError("Closed for editing")
super(RelatedModelForm, self).clean() # important- let admin do its work on data!
return cleaned_data
На мой взгляд, это не так уж много накладных расходов, но все же довольно просто и легко обслуживается.