web-dev-qa-db-fra.com

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 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?

182
Joelbitar

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.

267
Mike Axiak

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'}),
        }
54
Hamish Downer

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.

36
Mark

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
21

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})
        }
15
Dwayne Crooks