web-dev-qa-db-ja.com

DjangoのCharFieldにプレースホルダーを追加するにはどうすればよいですか?

たとえば、次の非常にシンプルなフォームをご覧ください。

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

これはテンプレートにレンダリングされます:

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

ただし、このフィールドにplaceholderの値を持つSearch属性を追加して、HTMLが次のようになるようにします。

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

できれば、プレースホルダーの値を辞書などのフォームクラスのCharFieldに渡したいと思います。

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

これを達成する最良の方法は何でしょうか?

182
Joelbitar

widgets documentation を見てください。基本的には次のようになります。

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

より多くの文章を作成できます。ただし、分離することで、より複雑なケースをより適切に抽象化できます。

widgetsサブクラスのMetaに直接<field name> => <widget instance>マッピングを含むModelForm属性を宣言することもできます。

267
Mike Axiak

ModelFormの場合、Metaクラスを次のように使用できます。

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

他の方法はすべて良いです。ただし、フィールドを指定しない場合(動的メソッドなど)、これを使用できます:

def __init__(self, *args, **kwargs):
    super(MyForm, self).__init__(*args, **kwargs)
    self.fields['email'].widget.attrs['placeholder'] = self.fields['email'].label or '[email protected]'

また、インスタンスが指定されたModelFormsのインスタンスにプレースホルダーが依存することもできます。

36
Mark

このコードを使用して、フォーム内のすべてのTextInputフィールドにプレースホルダーattrを追加できます。プレースホルダーのテキストは、モデルフィールドラベルから取得されます。

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

いい質問ですね。私が知っている3つの解決策があります:

ソリューション#1

デフォルトのウィジェットを置き換えます。

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

解決策2

デフォルトのウィジェットをカスタマイズします。フィールドが通常使用するウィジェットと同じウィジェットを使用している場合、まったく新しいウィジェットをインスタンス化する代わりに、ウィジェットをカスタマイズできます。

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'})

ソリューション#

最後に、モデルフォームで作業している場合、(に加えて、前の2つのソリューション)に加えて、カスタムウィジェットを指定するオプションがあります内部widgetsクラスのMeta属性を設定することにより、フィールド。

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