如何验证字段并获得验证的输出

时间:2018-09-18 23:09:41

标签: python

我正在尝试验证模型中的值,并获得经过验证的值作为输出。文档中唯一的示例是以下代码,该代码未显示此操作的执行方式,因此我无法对其进行扩展。

>>> from schematics.models import Model
>>> from schematics.types import StringType, BooleanType
>>> from schematics.exceptions import ValidationError
>>>
>>> class Signup(Model):
...     name = StringType()
...     call_me = BooleanType(default=False)
...     def validate_call_me(self, data, value):
...         if data['name'] == u'Brad' and data['call_me'] is True:
...             raise ValidationError(u'He prefers email.')
...         return value
...
>>> Signup({'name': u'Brad'}).validate()
>>> Signup({'name': u'Brad', 'call_me': True}).validate()
Traceback (most recent call last):
...
ModelValidationError: {'call_me': [u'He prefers email.']}

我制作了一个版本,但从参数中删除了datavalueClient是我的模型的名称。因此,当我执行以下操作时,将得到期望的结果作为输出:

client.validate_client(client.to_native())

但是,

  • 首先,这似乎不是一种干净的方法。 client已经具有所有值,因此我不需要这样做。

  • 此外,我喜欢获取它来更新客户端的值,作为验证的结果。

对于第一部分,我做了以下内容:

def validate_client(self):
    data = self.to_native()

    ...

    return data

但是我不认为这是执行此操作的最佳方法,并且我不确定第二个更新值的问题。有办法吗?

编辑:

这是我拥有的代码,我希望将雇主的客户值设置为'unspecified',并将客户full_name设置为函数中指定的值。

class LowerCaseEmailType(EmailType):

    def convert(self, value, context=None):
        value = super(LowerCaseEmailType, self).convert(value, context)
        return value.lower()


class CleanedStringType(StringType):
    converters = []

    def __init__(self, **kwargs):
        """
        This takes in all the inputs as String Type, but takes in an extra
        input called converters.
        Converters must be a list of functions, and each of those functions
        must take in exactly 1 value , and return the transformed input
        """
        if 'converters' in kwargs:
            self.converters = kwargs['converters']
        del kwargs['converters']
        super(CleanedStringType, self).__init__(**kwargs)

    def convert(self, value, context=None):
        value = super(CleanedStringType, self).convert(value, context)
        for func in self.converters:
            value = func(value)
        return value  # will have a value after going through all the conversions in order


class Client(Model):
    """
    Client Model
    """
    first_name = CleanedStringType(required=False,
                                   converters=[lambda x: re.sub(r"[!@#$%&\(\)\^]+", ' ', x),
                                               lambda x: x.strip()])
    last_name = CleanedStringType(required=False,
                                  converters=[lambda x: re.sub(r"[!@#$%&\(\)\^]+", ' ', x),
                                              lambda x: x.strip()])
    full_name = CleanedStringType(required=False,  
                                  converters=[lambda x: re.sub(r"[!@#$%&\(\)\^]+", ' ', x),
                                              lambda x: x.strip()])
    employer = StringType(required=False)
    created = StringType(default=" ")    
    updated = StringType(default=" ")     
    email = LowerCaseEmailType(required=False)

    def validate_client(self):
        data = self.to_native()

        if data.get('first_name') and data.get('last_name'):
            data['full_name'] = ' '.join([data['first_name'], data['last_name']])

        if data.get('full_name') is None:
            if data.get('first_name') is None:
                error_message = 'first name missing'
            else:
                error_message = 'last name missing'
            logger.error('info: {} for {}'.format(error_message, data))
            raise ValidationError(error_message)

        if data.get('employer') is None:
            logger.warning('info: employer missing for {}'.format(data))
            data['employer'] = 'unspecified'

        return data

1 个答案:

答案 0 :(得分:0)

我认为您想要pre_setattr。当您设置模型的值(有问题的code时,该值会被调用。

对于雇主,我想您要设置默认值。对我来说,这似乎完全符合您的要求。

我认为fullname不应放在模型上,因为firstname + lastname != fullname处的数据可能不一致。如果以后需要,可以通过@serialized来实现。