Не требовать поля, отличного от NULL (разрешить пустые строки) в FormAlchemy
-
12-09-2019 - |
Вопрос
Я новичок в 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
запрещает.Есть ли что-то вроде 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
на полях модели, потому что это тоже не кажется правильным решением.
Каков правильный способ проверки формы в таком случае?Заранее спасибо за любые предложения.
Решение
Наконец нашел (хороший, но, похоже, это единственный разумный выбор) способ сделать это.
fs.serial_number.validators.remove(formalchemy.validators.required)
fs.mac.validators.remove(formalchemy.validators.required)
(Относительно моего валидатора) Обратите внимание, что FA будет полностью пропустить всю проверку, когда значение равно None
, потому что по соглашению оно не пройдет None
валидаторам (кроме validators.required
, который жестко запрограммирован).Я подал запрос на улучшение, пытаясь решить эту проблему: http://code.google.com/p/formalchemy/issues/detail?id=117
Другие советы
Можете ли вы объяснить, почему nullable=True
не было бы решением?
Мне кажется бесполезным хранить пустые строки в базе данных, и я бы не поощрял это.Если данных нет, выберите более эффективный тип базы данных.
Лично я считаю, что решение Django в случае строк неверно, поскольку оно на самом деле не поддерживает NULL в CharFields.Если вы хотите сохранить NULL в CharField, вам придется сделать это вручную в коде.
Это точно такая же проблема, с которой я сталкиваюсь: я часто пишу интерфейсы для существующих баз данных и хочу использовать формалхимию, но в конечном итоге мне приходится вручную удалять «необходимость», поскольку я не могу изменить базу данных.
Вы можете научить FormAlchemy не заменять пустой ввод на None, изменив null_as
атрибут столбца.
whatever = Column(Unicode(999), required=False, null_as=("","\0"), nullable=False, default="", doc="Whatever for ever")
Формалхимия заменит входные данные, равные второму члену null_as
кортеж с None
.(Первый — это отображаемый текст для SELECT и подобных полей.)
Если вы установите это значение в строку, которую пользователь не сможет ввести, этого никогда не произойдет.