Django : les formulaires “sur mesure”
Voici les étapes lorsqu’on sort des sentiers battus et qu’on veut créer un formulaire sur mesure, ainsi qu’une vue sur mesure.
J’ai toujours eu besoin d’un ModelForm
: je garde les champs que je veux, voici un code basique qui crée le champ label
, avec toutes les traductions nécessaires :
class QuestionForm(forms.ModelForm):
class Meta:
model = Question
fields = ('label', )
e = {'required': _(u'This field is required'),
'invalid': _(u'This field contains invalid data')}
a = u'{}<span class="important-field">*</span>'.format(_(u'Question:'))
label = forms.CharField(
label=a, localize=True, required=True,
widget=widgets.TextInput(attrs={
'title': a,
'class': 'form-control form-control'}),
error_messages=e)
Ensuite pour cette classe, je crée un champ dynamiquement via le constructeur :
def __init__(self, *args, **kwargs):
super(QuestionForm, self).__init__(*args, **kwargs)
# -----------------------------------------------------
# Création dynamique de champs custom
# self.fields est de type OrderedDict(), qui se base
# sur l'ordre d'ajout des éléments. Alors si on veut
# un autre ordre, pas d'autre choix que de reconstruire
# le dictionnaire en y appliquant l'ordre qu'on veut :
#
# création dynamique de l'image :
a = _(u'Picture')
photo = ImageField(
label=a, allow_empty_file=True, required=False,
widget=forms.FileInput(attrs={
'title': a,
'placeholder': _(u'picture'),
'class': 'form-control',
'accept': "image/*", }),
error_messages=e)
new_fields = OrderedDict([
('label', self.fields['label']),
('photo', photo),
])
self.fields = new_fields