220 votes

Comment ajouter un espace réservé sur un CharField dans Django?

Prenez cet exemple de formulaire très simple par exemple :

class SearchForm(Form):
    q = forms.CharField(label='search')

Cela se retrouve rendu dans le template :

Cependant, je veux ajouter l'attribut placeholder à ce champ avec une valeur de Search afin que le HTML ressemble à quelque chose comme :

Idéalement, j'aimerais passer la valeur du placeholder à CharField dans la classe de formulaire à travers un dictionnaire ou quelque chose comme :

q = forms.CharField(label='search', placeholder='Search')

Quelle serait la meilleure façon d'accomplir cela ?

324voto

Mike Axiak Points 6349

Regardez la documentation sur les widgets. En gros, ça ressemblerait à :

q = forms.CharField(label='search', 
                    widget=forms.TextInput(attrs={'placeholder': 'Recherche'}))

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 mapping => directement dans le Meta de votre sous-classe de ModelForm.

0 votes

Avez-vous besoin de spécifier forms.TextInput pour faire la déclaration attrs={'placeholder': 'Search'} ?

1 votes

@OvedD, Je sais que c'est vieux, mais regardez cette question : stackoverflow.com/questions/4341739/…

1 votes

@OvedD: consultez ma réponse pour savoir comment faire cela avec un ModelForm

66voto

Hamish Downer Points 4086

Pour un ModelForm, vous pouvez utiliser la classe Meta comme ceci :

from django import forms

from .models import MyModel

class MyModelForm(forms.ModelForm):
    class Meta:
        model = MyModel
        widgets = {
            'name': forms.TextInput(attrs={'placeholder': 'Nom'}),
            'description': forms.Textarea(
                attrs={'placeholder': 'Entrez la description ici'}),
        }

0 votes

Notez que dans ce cas, vous ne pouvez pas spécifier le champ dans le corps de la classe.

0 votes

C'était la méthode la plus facile pour moi - et c'était agréable que tous les autres attributs (c.-à-d. requis) aient été automatiquement ajoutés sans que je doive les spécifier.

45voto

Mark Points 1278

Les autres méthodes sont toutes bonnes. Cependant, 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@address.nl'

Cela permet également au placeholder de dépendre de l'instance pour les ModelForms avec une instance spécifiée.

8 votes

C'est génial car ça évite d'avoir à dupliquer l'instanciation longue des widgets pour des objets plus compliqués tels que ModelMultipleChoiceField. Merci!

1 votes

Esprit similaire : for f in MyCommentForm.base_fields.values(): f.widget.attrs["placeholder"] = f.label, mais je préfère mieux votre méthode de constructeur.

29voto

dwayne Points 48

Grande question. Il y a trois solutions que je connais :

Solution #1

Remplacez le widget par défaut.

class SearchForm(forms.Form):  
    q = forms.CharField(
            label='Recherche',
            widget=forms.TextInput(attrs={'placeholder': 'Recherche'})
        )

Solution #2

Personnalisez le widget par défaut. Si vous utilisez le même widget que celui que le champ utilise généralement, vous pouvez simplement personnaliser celui-ci au lieu d'en instancier un totalement nouveau.

class SearchForm(forms.Form):  
    q = forms.CharField(label='Recherche')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['q'].widget.attrs.update({'placeholder': 'Recherche'})

Solution #3

Enfin, si vous travaillez avec un formulaire de modèle alors (en plus des deux solutions précédentes) vous avez la possibilité de spécifier un widget personnalisé pour un champ en définissant l'attribut widgets de la classe Meta interne.

class CommentForm(forms.ModelForm):  
    class Meta:
        model = Comment
        widgets = {
            'body': forms.Textarea(attrs={'cols': 80, 'rows': 20})
        }

21voto

Vous pouvez utiliser ce code pour ajouter l'attribut placeholder à chaque champ TextInput de votre formulaire. Le texte des placeholders sera extrait des libellés des champs du 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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X