J'ai une z3c.form utilisée lors de l'enregistrement. L'un des champs contient la liste des courriels auxquels les utilisateurs peuvent s'inscrire. Je souhaite que le premier d'entre eux soit sélectionné par défaut, alors que les autres ne devraient pas l'être. Je ne peux pas voir un moyen dans la spécification de le faire. Des idées?Case à cocher spécifique dans la liste z3c.form
Répondre
Le cas le plus simple est tel que documenté dans Modelling using zope.schema, default value section, ce qui correspond à z3c.form
(relevant documentation). Cependant, cela est compliqué par le fait que les valeurs par défaut ne doivent pas être mutables car l'instance est partagée à travers tout, donc par sécurité un argument defaultFactory
est implémenté pour gérer cela. Mettre tout cela ensemble, vous devriez avoir quelque chose comme ceci:
import zope.schema
import zope.interface
from zope.schema.vocabulary import SimpleVocabulary
emailVocab = SimpleVocabulary.fromItems((
('sysn', u'System notifications (strongly recommended)'),
('mark', u'Marketing emails'),
('offe', u'Special offers')))
def default_email():
return [u'Special offers'] # example
class IEmailPreference(zope.interface.Interface):
# ...
email_optin = zope.schema.List(
title=u'',
description=u'',
required=False,
value_type=zope.schema.Choice(source=emailVocab),
defaultFactory=default_email,
)
Prenez note que la valeur réelle utilisée pour la valeur par défaut est pas la partie token
mais la partie value
, d'où la chaîne 'Special offers'
est retourné au lieu de 'offe'
. Il est documenté in the documentation about Vocabularies. Si la partie lisible par un humain est destinée à être le titre et que vous souhaitez que la valeur réelle soit la même que celle du jeton, vous devrez ajuster votre code en conséquence. Sinon, pour sélectionner le premier, vous avez simplement default_email
return [u'System notifications (strongly recommended)']
.
Pour être complet, votre module de formulaire pourrait ressembler à ceci:
from z3c.form.browser.checkbox import CheckBoxFieldWidget
from z3c.form.form import Form
class EmailPreferenceForm(Form):
fields = z3c.form.field.Fields(IEmailPreference)
fields['email_optin'].widgetFactory = CheckBoxFieldWidget
Vous pouvez également utiliser discriminateurs de valeur pour aborder ce problème si vous ne souhaitez pas remplir l'interface avec une valeur par défaut ou une usine pour cela, mais c'est beaucoup plus d'effort pour mettre en place donc j'évite généralement de faire face à cela quand c'est assez bon.
J'aurais dû cocher ça il y a longtemps. Merci beaucoup. – chrism