【问题标题】:Do not require non-NULL field (allow empty strings) in FormAlchemy在 FormAlchemy 中不需要非 NULL 字段(允许空字符串)
【发布时间】:2010-11-30 09:39:55
【问题描述】:

我是 FormAlchemy 的新手,我似乎没有得到任何东西。我有一个这样定义的 SQLAlchemy 模型:

...
class Device(meta.Base):
    __tablename__ = 'devices'

    id = sa.Column('id_device', sa.types.Integer, primary_key=True)
    serial_number = sa.Column('sn', sa.types.Unicode(length=20), nullable=False)
    mac = sa.Column('mac', sa.types.Unicode(length=12), nullable=False)
    ipv4 = sa.Column('ip', sa.types.Unicode(length=15), nullable=False)
    type_id = sa.Column('type_id', sa.types.Integer,
                        sa.schema.ForeignKey('device_types.id'))
    type = orm.relation(DeviceType, primaryjoin=type_id == DeviceType.id)
...

然后在我的(Pylons)控制器中创建一个 FormAlchemy 表单,如下所示:

c.device = model.meta.Session.query(model.Device).get(device_id)
fs = FieldSet(c.device, data=request.POST or None)
fs.configure(options=[fs.ipv4.label(u'IP').readonly(),
                      fs.type.label(u'Type').with_null_as((u'—', '')),
                      fs.serial_number.label(u'S/N'),
                      fs.mac.label(u'MAC')])

文档说“默认情况下,NOT NULL 列是必需的。您只能添加必需性,而不是删除它。”,但我想允许非 NULL 空字符串,validators.required 不允许。 Django中有blank=True, null=False之类的东西吗?

更准确地说,我想要一个像下面这样的自定义验证器,允许使用 type=None 的空字符串或将所有值设置为非 NULL 和非空:

# For use on fs.mac and fs.serial_number.
# I haven't tested this code yet.
def required_when_type_is_set(value, field):
    type_is_set = field.parent.type.value is not None:
    if value is None or (type_is_set and value.strip() = ''):
        raise validators.ValidationError(u'Please enter a value')

如果可能的话,我想避免给猴子打补丁formalchemy.validators.required 或其他东西。我不想在模型字段上设置nullable=True,因为它似乎也不是正确的解决方案。

在这种情况下验证表单的正确方法是什么?提前感谢您的任何建议。

【问题讨论】:

    标签: python sqlalchemy validation pylons formalchemy


    【解决方案1】:

    你能解释一下为什么nullable=True 不是解决方案吗?

    对我来说,在数据库中存储空字符串似乎没用,我不鼓励这样做。如果没有数据比为数据库选择更有效的类型。

    我个人认为字符串情况下的 Django 解决方案是错误的,因为它并不真正支持 CharFields 中的 NULL。如果您想将 NULL 存储在 CharField 中,则必须在代码中手动进行。

    【讨论】:

    • 感谢您的建议,也许您是对的。对此事众说纷纭:stackoverflow.com/questions/265875/…。无论如何,答案很简单而且不是那么幸运——它已经存在(“遗留”)数据库支持。已经有相当多的代码使用该数据库,约定是为“无值”存储空字符串并避免 NULL。
    【解决方案2】:

    终于找到了一个kludge,但似乎这是唯一理智的方法:

      fs.serial_number.validators.remove(formalchemy.validators.required)
      fs.mac.validators.remove(formalchemy.validators.required)
    

    对于验证器函数,当值为 None 时,FA 将完全跳过所有验证,因为按照惯例,它不会将 None 传递给验证器(@ 时除外987654325@ 已设置,这是硬编码的)。我已提交增强请求 ticket 试图解决此问题。

    【讨论】:

      【解决方案3】:

      这与我遇到的问题完全相同,我经常为现有数据库编写接口并希望使用形式化学,但最终不得不手动删除“必需”,因为我无法更改数据库。

      【讨论】:

        【解决方案4】:

        您可以通过更改 null_as 列属性来教 FormAlchemy 不要用 None 替换空输入。

         whatever = Column(Unicode(999), required=False, null_as=("","\0"), nullable=False, default="", doc="Whatever for ever")
        

        Formalchemy 会将等于null_as 元组的第二个成员的输入替换为None。 (第一个是 SELECT 和类似字段的显示文本。)

        如果您将其设置为用户无法输入的字符串,这将永远不会发生。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-12
          • 1970-01-01
          • 2019-06-01
          • 2012-12-13
          • 2015-10-04
          • 2017-05-28
          相关资源
          最近更新 更多