2009-06-15 10 views
2

J'ai une application Pylons et j'utilise FormEncode et HtmlFill pour gérer mes formulaires. J'ai un tableau de champs de texte dans mon modèle (Mako)Pylônes FormEncode avec un tableau d'éléments de formulaire

 
    <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 ne peux pas à comprendre comment valider ces champs. Voici l'entrée correspondante de mon schéma

yardage = formencode.ForEach(formencode.validators.Int())

Je suis en train de vérifier que chacun de ces champs est un Int. Toutefois, aucune validation ne se produit pour ces champs.

MISE À JOUR Comme demandé ici est le code pour l'action de ce contrôleur. Je sais que cela fonctionnait comme 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') 

MISE À JOUR Il a été suggéré sur IRC que je change le nom des éléments yardage[]-yardage Aucun résultat. Ils devraient tous être ints mais mettre dans un des éléments ne le rend pas invalide. Comme je l'ai déjà dit, je suis capable de valider d'autres champs de formulaire. Voici mon schéma complet.

 
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()) 
+0

Pourriez-vous partager un peu plus de code, pas moins le code du contrôleur? – ayaz

Répondre

5

Il s'avère que ce que je voulais faire n'était pas tout à fait raison.

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û faire dans une boucle pour commencer.) Vous remarquerez que le nom du premier élément deviendra hole-1.yardage. Je vais ensuite utiliser FormEncode.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 HoleSchema validera que hole-#.par et hole-#.yardage sont les deux ints et ne sont pas vides. formencode.ForEach me permet d'appliquer HoleSchema au dictionnaire que je reçois de passer variable_decode=True au décorateur @validate.

Voici l'action submit de mon

Controller:

@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!' 

Utilisation du décorateur @validate permet une beaucoup plus propre moyen de valider et de remplir les formulaires. Le variable_decode=True est très important ou le dictionnaire ne sera pas créé correctement.

1
c.form_result = schema.to_python(request.params) - (without dict) 

Cela semble fonctionner correctement.

Questions connexes