创建后如何禁止更改Django字段?

时间:2018-10-05 00:55:18

标签: django django-rest-framework

我有一个这样的模型:

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,验证必须在服务器端进行。

0 个答案:

没有答案