Pylônes formemcode avec un tableau d'éléments de forme
-
13-09-2019 - |
Question
J'ai une application de pylônes et j'utilise Formencode et HTMLFill pour gérer mes formulaires. J'ai une gamme de champs de texte dans mon modèle (Mako)
<tr> <td>Yardage</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> <td>${h.text('yardage[]', maxlength=3, size=3)}</td> </tr>
Cependant, je n'arrive pas à comprendre comment valider ces champs. Voici l'entrée pertinente de mon schéma
yardage = formencode.ForEach(formencode.validators.Int())
J'essaie de valider que chacun de ces champs est un int. Cependant, aucune validation ne se produit pour ces champs.
METTRE À JOURComme demandé, voici le code de l'action de ce contrôleur. Je sais que cela fonctionnait car je peux valider d'autres champs de formulaire.
def submit(self): schema = CourseForm() try: c.form_result = schema.to_python(dict(request.params)) except formencode.Invalid, error: c.form_result = error.value c.form_errors = error.error_dict or {} c.heading = 'Add a course' html = render('/derived/course/add.html') return htmlfill.render( html, defaults = c.form_result, errors = c.form_errors ) else: h.redirect_to(controler='course', action='view')
METTRE À JOURIl a été suggéré sur IRC que je change le nom des éléments de yardage[]
à yardage
Pas de résultat. Ils devraient tous être INTS, mais mettre F dans l'un des éléments ne fait pas que cela ne soit pas valide. Comme je l'ai déjà dit, je suis en mesure de valider d'autres champs de formulaire. Ci-dessous, tout mon schéma.
import formencode class CourseForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True name = formencode.validators.NotEmpty(messages={'empty': 'Name must not be empty'}) par = formencode.ForEach(formencode.validators.Int()) yardage = formencode.ForEach(formencode.validators.Int())
La solution
Il s'avère que ce que je voulais faire n'était pas tout à fait correct.
Modèle:
<tr>
<td>Yardage</td>
% for hole in range(9):
<td>${h.text('hole-%s.yardage'%(hole), maxlength=3, size=3)}</td>
% endfor
</tr>
(Aurait dû se rendre dans une boucle pour commencer.) Vous remarquerez que le nom du premier élément deviendra hole-1.yardage
. J'utiliserai alors Formmencode.variabledEcode
pour transformer cela en dictionnaire. Cela se fait dans le
Schéma:
import formencode
class HoleSchema(formencode.Schema):
allow_extra_fields = False
yardage = formencode.validators.Int(not_empty=True)
par = formencode.validators.Int(not_empty=True)
class CourseForm(formencode.Schema):
allow_extra_fields = True
filter_extra_fields = True
name = formencode.validators.NotEmpty(messages={'empty': 'Name must not be empty'})
hole = formencode.ForEach(HoleSchema())
Le trouschema va valider cela hole-#.par
et hole-#.yardage
sont les deux INTS et ne sont pas vides. formencode.ForEach
me permet de postuler HoleSchema
au dictionnaire que j'obtiens de passer variable_decode=True
au @validate
décorateur.
Voici la submit
Action de mon
Manette:
@validate(schema=CourseForm(), form='add', post_only=False, on_get=True,
auto_error_formatter=custom_formatter,
variable_decode=True)
def submit(self):
# Do whatever here.
return 'Submitted!'
En utilisant le @validate
Le décorateur permet un moyen beaucoup plus propre de valider et de remplir les formulaires. La variable_decode=True
est très important ou le dictionnaire ne sera pas correctement créé.
Autres conseils
c.form_result = schema.to_python(request.params) - (without dict)
Cela semble bien fonctionner.