Не требовать не пустое поле (разрешить пустые строки) в FormAlchemy - PullRequest
3 голосов
/ 22 сентября 2009

Я довольно новичок в 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 в Django?

Чтобы быть более точным, я хочу, чтобы пользовательский валидатор, подобный приведенному ниже, позволял либо пустым строкам с type=None, либо всем значениям быть ненулевыми и непустыми:

# 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 в полях модели, потому что это тоже не является правильным решением.

Какой правильный способ проверки формы в таком случае? Спасибо за любые предложения заранее.

Ответы [ 4 ]

4 голосов
/ 23 сентября 2009

Наконец-то нашел (klugde, но, похоже, это единственный разумный выбор) способ сделать это.

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

(Относительно моего валидатора) Обратите внимание, что FA будет полностью пропускать все проверки, когда значение None, потому что, по соглашению, оно не будет передавать None валидаторам (кроме 1008 *, что жестко закодировано). Я подал заявку на улучшение, пытаясь решить эту проблему: http://code.google.com/p/formalchemy/issues/detail?id=117

3 голосов
/ 23 сентября 2009

Можете ли вы объяснить, почему nullable=True не будет решением?

Мне кажется бесполезным хранить пустые строки в базе данных, и я бы не стал поощрять это. Если данных нет, выберите более эффективный тип для базы данных.

Лично я считаю, что решение Django в случае строк неверно, поскольку оно не поддерживает NULL в CharFields. Если вы хотите сохранить NULL в CharField, вам придется сделать это вручную в коде.

0 голосов
/ 31 мая 2014

Вы можете научить FormAlchemy не заменять пустой ввод на None, изменив атрибут столбца null_as.

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

Формалхимия заменит вход, равный второму члену кортежа null_as, на None. (Первым является отображаемый текст для SELECT и подобных полей.)

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

0 голосов
/ 19 декабря 2010

Это точно такая же проблема, как и у меня, когда я часто пишу интерфейсы для существующих баз данных и хочу использовать формальную химию, но в итоге мне приходится вручную удалять «обязательность», поскольку я не могу изменить базу данных.

...