У меня есть такая модель:
THRESHOLD_CLASSES = {
MinimumThreshold.name: MinimumThreshold,
MaximumThreshold.name: MaximumThreshold
}
class Threshold(models.Model):
thingie = models.ForeignKey(Thingie, models.CASCADE)
threshold_types = THRESHOLD_CLASSES.keys()
type = models.TextField(choices=zip(threshold_types, threshold_types))
threshold = models.DecimalField()
Со следующими родственными классами:
import abc
import operator
class Threshold(abc.ABC):
@abc.abstractmethod
def __init__(self):
pass
class MinimumThreshold(Threshold):
name = 'minimum'
operator = operator.lt
operator_name = 'lower than'
def __init__(self):
self.other_class = MaximumThreshold
class MaximumThreshold(Threshold):
name = 'maximum'
operator = operator.gt
operator_name = 'greater than'
def __init__(self):
self.other_class = MinimumThreshold
В моем сериализаторе я должен убедиться, что минимальный порог для thingie
меньше его максимума:
def validate(self, instance):
instance_type = instance['type']
instance_threshold_class = models.THRESHOLD_CLASSES[instance_type]
other_threshold_class = instance_threshold_class().other_class
other = models \
.AlarmParameterThreshold \
.objects \
.filter(thingie=instance['thingie'], type=other_threshold_class.name) \
.first()
if other:
if other_threshold_class.operator(instance['threshold'], other.threshold):
message = "The {} threshold cannot be {} the {} threshold of {}".format(
instance_type,
other_threshold_class.operator_name,
other_threshold_class.name,
other.threshold
)
raise serializers.ValidationError({'threshold': message})
Это уже сложно, и я хочу убедиться, что сложность не взорвется.Один в настоящее время необработанный случай, когда пользователь меняет type
существующего Threshold
- я бы в конечном итоге сравнил его с экземпляром, который должен быть заменен, и поэтому мне нужно убедиться, чточтобы исключить экземпляр, который в данный момент обновляется, из запроса, чтобы найти другой порог.
В этом случае более простым подходом было бы просто запретить изменения type
после его установки, но я не знаю способа сделать это проще, чем исключить текущий элемент из сравнения.
Обратите внимание, что я не ищу решение для Django Forms - это APIи проверка должна быть выполнена на стороне сервера.