SQLAlchemy验证和额外参数

时间:2017-04-21 16:00:51

标签: python python-3.x sqlalchemy

根据SQLAlchemy文档,我知道我可以使用Model的列设置验证器:

def validate_phone(target, value, oldvalue, initiator):
    "Strip non-numeric characters from a phone number"

    return re.sub(r'(?![0-9])', '', value)  

# setup listener on UserContact.phone attribute, instructing
# it to use the return value 
listen(UserContact.phone, 'set', validate_phone, retval=True)

但我想将额外的参数传递给验证器,例如:

def check_range(target, value, oldvalue, initiator, begin, end)
    if value in range(begin, end):
        return value
    else:
        raise ValidationError()

我如何在侦听器中配置此验证器,以便它接受额外的参数 begin end

1 个答案:

答案 0 :(得分:1)

好的,我通过在我的Column定义中添加一个参数来解决它(我已经定义了一个继承自Column以添加额外参数的RsColumn类),其中包含一个带有validator-function-names和可选参数作为kwargs的dict。 / p>

当我的应用程序启动时,它解析所有模型并检查

中的列上是否定义了自定义验证器
def check_positive(value, field):
    # do stuff
    pass


def check_range(value, field, begin, end):
    # do range checking
    pass


def execute_field_validations(model_instance, value, old_value, initiator):
    """
    When a "set" event is given on a models field/column then execute
    all the fields validators optionally with arguments as described 
    in the model's definition in db.models

    for example VehicleType.loading_meters:

        loading_meters = RsColumn(..., validators=[
            {"function": "check_positive"},
            {"function": "check_range", "kwargs": {"begin": 0, "end": 1000}}
        ], ...)
    """
    field = model_instance.__mapper__.columns[initiator.key]

    for validator in field.validators:

        try:
            assert validator["function"] in globals(), \
                "Invalid validator '{0}' in column ".format(
                    validator["function"]
                )

            validator_function = globals()[validator["function"]]

            if "kwargs" in validator:
                validator_function(value, field, **validator["kwargs"])
            else:
                validator_function(value, field)

        except Exception as e:
             raise ValueError()         

def configure_validators_on_individual_fields(base):
    """
    Parse through all models and all defined columns/fields
    and see if there are individual validators set on them.
    If so add a listser for them on the "set"-event
    """
    for table in base.metadata.tables:
        for field in base.metadata.tables[table].columns:
            if field.validators:
                listen(
                    getattr(
                        get_class_by_tablename(table),
                        field.name
                    ), 
                    "set", 
                    execute_field_validations
                )

- 列中的参数。它设置了一个监听器" set"执行函数" execute_field_validations"它再次解析所有"验证器"在字段中,如果给出了参数,则可以选择性地执行它们。

@Html.LabelForModel()