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