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

Prenez cette forme très simple par exemple.

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

Ceci est rendu dans le modèle:

<input type="text" name="q" id="id_q" />

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

<input type="text" name="q" id="id_q" placeholder="Search" />

De préférence, je voudrais passer la valeur de l'espace réservé à CharField dans la classe form via un dictionnaire ou quelque chose comme:

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

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

159
demandé sur Paco 2010-11-04 23:51:57

5 réponses

Regardez la documentation 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 de cas plus compliqués.

Vous pouvez également déclarer un attribut widgets contenant un mappage <field name> => <widget instance> directement sur le Meta de votre sous-classe ModelForm.

229
répondu Mike Axiak 2014-10-13 18:39:31

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'}),
        }
50
répondu Hamish Downer 2013-10-15 15:31:42

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'

Il permet également à L'espace réservé de dépendre de L'instance pour ModelForms avec l'instance spécifiée.

33
répondu Mark 2015-10-31 18:04:31

Vous pouvez utiliser ce code pour ajouter un espace réservé attr pour chaque champ TextInput de votre formulaire. Le texte des espaces réservés sera extrait des étiquettes de champ 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
20
répondu Yevgeniy Shchemelev 2014-02-07 22:03: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='Search',
            widget=forms.TextInput(attrs={'placeholder': 'Search'})
        )

Solution #2

Personnalisez 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 #3

Enfin, si vous travaillez avec un formulaire de modèle alors (en plus de la précédente deux solutions ) vous avez la possibilité de spécifier un widget personnalisé pour un 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})
        }
11
répondu Dwayne Crooks 2017-09-25 20:47:50