Web2py 字段值依赖于另一个字段——(定义模型时验证)

Web2py Field value depends on another field - (validate while defining the model)

请考虑以下内容table:

db.define_table('bio_data',
            Field('name', 'string'),
            Field('total_mark', 'integer', requires=IS_EMPTY_OR(IS_INT_IN_RANGE(0, 1e100))),
            Field('marks_obtained', 'integer')
            )

现在字段 'marks_obtained' 的值不能大于 'total_marks'。

我试过以下方法

db.bio_data.marks_obtained.requires = IS_EMPTY_OR(
IS_INT_IN_RANGE(0, db.bio_data.total_mark))

但这不起作用。我收到以下错误:

TypeError: int() argument must be a string or a number, not 'Field'

非常感谢任何帮助。

您可以使用 onvalidation 回调函数轻松完成此操作。读这个 Form and validators - onvalidation

第二种解决方案是您需要将“Validators with dependencies”和IS_EXPR validator 结合起来。阅读:

  1. Validators with dependencies

  2. IS_EXPR

controller 中添加验证器,如下所示,我没有测试过,但你会从中得到一些想法。

is_total_less = int(request.vars.marks_obtained) < int(request.vars.total_mark)

db.bio_data.marks_obtained.requires = IS_EMPTY_OR(
IS_EXPR('%s' % is_total_less,
        error_message='Marks Obtained should be smaller than Totak Marks'))

确保 request.vars 可用。

我遇到了同样的问题,我刚刚找到了一个优雅的解决方案。首先,您需要注意,在任何验证之前,字段的值会传送到模型,因此,在模型中,您可以通过 request.vars 操作它们。在那之后,其他一切都很简单:只需创建一个您自己的验证器,提取字段的值并根据需要使用它们。举个例子会更好:

假设您有一个包含两个字段的 table:

    dbOBJECT.define_table("example",
                          Field("high_number",
                                "integer",
                                label= T('High number'),
                                requires=[IS_NOT_EMPTY(T(stringBuilder.emptyField))]),
                          Field("other_number",
                                "integer",
                                label= T('Lower number'),
                                requires=IS_NOT_EMPTY(T(stringBuilder.emptyField))))

并且您需要第二个数字小于第一个数字。出于解释的目的,让我们创建一个自定义验证器。这可以在同一个 db.py 文件

中完成
    class VALIDATE_NUMBERS(object):
        def __init__(self, error_message="Error, this value can't be greather than the above one"):
            self.error_message = error_message

        def __call__(self, value):
            error = None
            high_number=request.vars['high_number']

            if high_number < value:
                error = self.error_message
            return (value, error)

好吧,另一件事是在模型中包含此验证:

    dbOBJECT.define_table("example",
                          Field("high_number",
                                "integer",
                                label= T('High number'),
                                requires=[IS_NOT_EMPTY(T(stringBuilder.emptyField))]),
                          Field("other_number",
                                "integer",
                                label= T('Lower number'),
                                requires=IS_NOT_EMPTY [(T(stringBuilder.emptyField)), VALIDATE_NUMBERS()]))

魔法完成了!!!享受...