FormAlchemy 中不需要非 NULL 字段(允许空字符串)
我对 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 ,因为它似乎也不是正确的解决方案。
在这种情况下验证表单的正确方法是什么?感谢您提前提出任何建议。
I'm fairly novice to FormAlchemy and it seems that I don't get something. I have a SQLAlchemy model defined like this:
...
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)
...
Then in my (Pylons) controller I create a FormAlchemy form like this:
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')])
The documentation says that "By default, NOT NULL columns are required. You can only add required-ness, not remove it.", but I want to allow non-NULL empty strings, which validators.required
disallows. Is there something like blank=True, null=False
in Django?
To be more precise, I want a custom validator like one below, to either allow empty strings with type=None
or all values to be set non-NULL and non-empty:
# 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')
If possible, I'd like to refrain from monkey-patching formalchemy.validators.required
or other kludges. I don't want to set nullable=True
on model fields, because it doesn't seems to be proper solution too.
What's the correct way to validate form in such case? Thanks for any suggestions in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
终于找到了一个拼凑的办法,但似乎这是唯一明智的方法:
对于验证器函数,当值为
None
时,FA 将完全跳过所有验证,因为按照惯例,它不会将None
传递给验证器(除非设置validators.required
,这是硬编码的)。我已提交增强请求票据,试图解决此问题。Finally found a kludge, but it seems this is the only sane way to do it:
For the validator function, that FA will completely skip all validation when the value is
None
, because, by convention, it won't passNone
to validators (except for whenvalidators.required
is set, which is hard-coded). I've filed an enhancement request ticket trying to solve this.您能解释一下为什么
nullable=True
不是解决方案吗?对我来说,在数据库中存储空字符串似乎毫无用处,我不鼓励这样做。如果没有数据,则选择更有效的数据库类型。
我个人认为 Django 对于字符串的解决方案是错误的,因为它并不真正支持 CharFields 中的 NULL。如果您想将 NULL 存储在 CharField 中,则必须在代码中手动执行此操作。
Can you explain why
nullable=True
would not be the solution?To me it seems useless to store empty strings in the database and I would not encourage it. If there is no data than choose the more efficient type for the database.
Personally I think the Django solution in case of strings is wrong since it does not really support NULL in CharFields. If you want to store NULL in a CharField you will have to do it manually in the code.
这与我遇到的问题完全相同,我经常为现有数据库编写接口并希望使用形式化学,但最终不得不手动删除“必需性”,因为我无法更改数据库。
This is exactly the same issue i'm having, where I often write interfaces for existing databases and want to use formalchemy but end up having to manually remove 'requiredness' as I am not able to change the database.
您可以通过更改
null_as
列属性来教导 FormAlchemy 不要将空输入替换为 None。Formalchemy 会将等于
null_as
元组第二个成员的输入替换为None
。 (第一个是 SELECT 和类似字段的显示文本。)如果将其设置为用户无法输入的字符串,则这种情况永远不会发生。
You can teach FormAlchemy to not replace an empty input with None by changing the
null_as
column attribute.Formalchemy will replace input that's equal to the second member of the
null_as
tuple withNone
. (The first is the display text for SELECTs and similar fields.)If you set that to a string the user cannot input, this will never happen.