Question

Je suis assez novice à FormAlchemy et il semble que je ne comprends pas quelque chose. J'ai un modèle SQLAlchemy défini comme ceci:

...
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)
...

Ensuite, dans mon contrôleur (Pylons) Je crée une forme FormAlchemy comme ceci:

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')])

La documentation indique que « Par défaut, les colonnes NOT NULL sont requises. Vous ne pouvez ajouter-ness nécessaire, ne pas le retirer. », Mais je veux permettre à des chaînes vides non NULL, qui validators.required autorise pas. Y at-il quelque chose comme blank=True, null=False dans Django?

Pour être plus précis, je veux un validateur personnalisé comme celui ci-dessous, soit permettre à des chaînes vides avec type=None ou toutes les valeurs à définir non NULL et non vide:

# 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')

Si possible, je voudrais éviter de formalchemy.validators.required-patcher singe ou d'autres bidouilles. Je ne veux pas mettre nullable=True sur les champs de modèle, car il ne semble pas être une solution appropriée aussi.

Quelle est la bonne façon de valider le formulaire dans ce cas? Merci pour toutes suggestions à l'avance.

Était-ce utile?

La solution

Enfin trouvé un (klugde, mais semble que ce soit le seul choix sain d'esprit) façon de le faire.

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

(En ce qui concerne mon validateur) Notez que FA complètement sauter toutes validation lorsque la valeur est None, parce que, par convention, il ne passera pas None à validateurs (sauf pour validators.required, qui est codé en dur). J'ai déposé un billet de demande d'amélioration à essayer de résoudre ceci: http: / /code.google.com/p/formalchemy/issues/detail?id=117

Autres conseils

Pouvez-vous expliquer pourquoi nullable=True ne serait pas la solution?

Pour moi, il semble inutile de stocker des chaînes vides dans la base de données et je ne l'encourager. S'il n'y a pas de données que choisir le type plus efficace pour la base de données.

Personnellement, je pense que la solution Django en cas de chaînes est erroné car il ne supporte pas vraiment NULL dans CharFields. Si vous souhaitez stocker NULL dans un CharField vous devrez le faire manuellement dans le code.

Ceci est exactement le même problème que je vais avoir, où je vous écris souvent des interfaces pour bases de données existantes et que vous souhaitez utiliser FormAlchemy mais finissent par avoir à supprimer manuellement « requiredness » que je ne suis pas en mesure de changer la base de données.

Vous pouvez enseigner FormAlchemy de ne pas remplacer une entrée vide avec aucun en changeant l'attribut de colonne null_as.

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

FormAlchemy remplacera entrée qui est égal au second élément du tuple de null_as avec None. (Le premier est le texte d'affichage pour CHOISISSE champs similaires.)

Si vous définissez que sur une chaîne que l'utilisateur ne peut pas entrée, cela ne se produira jamais.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top