Prenez cette forme très simple par exemple:
class SearchForm(Form):
q = forms.CharField(label='search')
Ceci est rendu dans le template:
<input type="text" name="q" id="id_q" />
Cependant, je souhaite ajouter l'attribut placeholder
à ce champ avec une valeur de Search
afin que le code HTML ressemble à quelque chose comme:
<input type="text" name="q" id="id_q" placeholder="Search" />
De préférence, j'aimerais transmettre la valeur de marque de réservation à CharField
de la classe de formulaire à l'aide d'un dictionnaire ou de quelque chose comme:
q = forms.CharField(label='search', placeholder='Search')
Quel serait le meilleur moyen d'y parvenir?
Regardez le documentation des widgets . Fondamentalement, cela ressemblerait à:
q = forms.CharField(label='search',
widget=forms.TextInput(attrs={'placeholder': 'Search'}))
Plus d'écriture, oui, mais la séparation permet une meilleure abstraction des cas plus compliqués.
Vous pouvez également déclarer un attribut widgets
contenant un <field name> => <widget instance>
mappage directement sur le Meta
de votre sous-classe ModelForm
.
Pour un ModelForm, vous pouvez utiliser la classe Meta ainsi:
from Django import forms
from .models import MyModel
class MyModelForm(forms.ModelForm):
class Meta:
model = MyModel
widgets = {
'name': forms.TextInput(attrs={'placeholder': 'Name'}),
'description': forms.Textarea(
attrs={'placeholder': 'Enter description here'}),
}
Les autres méthodes sont toutes bonnes. Toutefois, si vous préférez ne pas spécifier le champ (par exemple, pour une méthode dynamique), vous pouvez utiliser ceci:
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['email'].widget.attrs['placeholder'] = self.fields['email'].label or '[email protected]'
Cela permet également à l’espace réservé de dépendre de l’instance pour ModelForms avec l’instance spécifiée.
Vous pouvez utiliser ce code pour ajouter un espace réservé attr pour chaque champ TextInput de votre formulaire. Le texte pour les espaces réservés sera pris à partir des étiquettes de champ de modèle.
class PlaceholderDemoForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(PlaceholderDemoForm, self).__init__(*args, **kwargs)
for field_name in self.fields:
field = self.fields.get(field_name)
if field:
if type(field.widget) in (forms.TextInput, forms.DateInput):
field.widget = forms.TextInput(attrs={'placeholder': field.label})
class Meta:
model = DemoModel
Excellente question. Je connais trois solutions:
Solution # 1
Remplace le widget par défaut.
class SearchForm(forms.Form):
q = forms.CharField(
label='Search',
widget=forms.TextInput(attrs={'placeholder': 'Search'})
)
Solution n ° 2
Personnaliser le widget par défaut. Si vous utilisez le même widget que le champ utilise habituellement, vous pouvez simplement personnaliser celui-ci au lieu d’instancier un tout nouveau.
class SearchForm(forms.Form):
q = forms.CharField(label='Search')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['q'].widget.attrs.update({'placeholder': 'Search'})
Solution #
Enfin, si vous utilisez un formulaire type, alors ( en plus des deux solutions précédentes ), vous avez la possibilité de spécifier un widget personnalisé pour une champ en définissant l'attribut widgets
de la classe interne Meta
.
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
widgets = {
'body': forms.Textarea(attrs={'cols': 80, 'rows': 20})
}