Google 数据存储 NDB 验证可选的 IntegerProperty

Google Datastore NDB validate optional IntegerProperty

如何验证空表单字段字符串 '' 以将 None 分配给 IntegerProperty?

class MyIntegerProperty(ndb.IntegerProperty):
    def _validate(self, value):
        if isinstance(value, basestring):
            if len(value) == 0 and self._required is False:
                return ?????????????????
            try:
                value = int(value)
            except ValueError:
                raise BadValueError(u'{0} must be a valid ' 
                    'integer'.format(self._name))
        if value < 0:
            raise BadValueError(u'{0} must be ' 
                'positive'.format(self._name))
        return value

class Account(ndb.Model):
    posint = MyIntegerProperty()

Docs say:

Things that _validate(), _to_base_type() and _from_base_type() do not need to handle:

None: They will not be called with None (and if they return None, this means that the value does not need conversion).

我目前正在做的是人工处理案件:

if len(request.form[name]) == 0:
    delattr(entity, name)
else:
    setattr(entity, name, request.form[name])

还能比这更聪明吗?

验证器可以生成 属性 值或引发异常,从而阻止实体被保存。来自 Property Options table:

Will be called with arguments (prop, value) and should either return the (possibly coerced) value or raise an exception. Calling the function again on a coerced value should not modify the value further. (For example, returning value.strip() or value.lower() is fine, but not value + '$'.) May also return None, which means "no change". See also Writing Property Subclasses

但是上面的none才是你真正想要的,就是删除属性。注意:

  • 设置 None 的 属性 值(例如,对于 IntegerProperty 会失败)与删除 属性 不同(完全可以 IntegerProperty)
  • 在使用验证器时设置 属性 值 None 可能会很棘手,因为从验证器返回 None 意味着 no change.

所以我相信你必须保持目前对这种情况的处理。