Не требовать поля, отличного от NULL (разрешить пустые строки) в FormAlchemy

StackOverflow https://stackoverflow.com/questions/1459919

Вопрос

Я новичок в 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 и подобных полей.)

Если вы установите это значение в строку, которую пользователь не сможет ввести, этого никогда не произойдет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top