Возьмите эту очень простую форму, например.
class SearchForm(Form):
q = forms.CharField(label='search')
Это отображается в шаблоне:
<input type="text" name="q" id="id_q" />
Однако я хочу добавить атрибут "placeholder" в это поле со значением "Поиск", чтобы HTML выглядел примерно так:
<input type="text" name="q" id="id_q" placeholder="Search" />
Я хотел бы передать значение placeholder в CharField в классе формы через словарь или что-то вроде:
q = forms.CharField(label='search', placeholder='Search')
Каким будет лучший способ достичь этого?
Посмотрите документацию по виджетам. В основном это выглядело бы так:
q = forms.CharField(label='search',
widget=forms.TextInput(attrs={'placeholder': 'Search'}))
Больше написания, да, но разделение позволяет лучше абстрагировать более сложные случаи.
Вы также можете объявить атрибут widgets
, содержащий сопоставление <field name> => <widget instance>
непосредственно на Meta
вашего подкласса ModelForm
.
Для 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'}),
}
Другие методы хороши. Однако, если вы предпочитаете не указывать поле (например, для некоторого динамического метода), вы можете использовать это:
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 с указанным экземпляром.
ModelMultipleChoiceField
. Спасибо!
for f in MyCommentForm.base_fields.values(): f.widget.attrs["placeholder"] = f.label
, но мне больше нравится ваш метод конструктора.
Вы можете использовать этот код, чтобы добавить placeholder attr для каждого поля TextInput в вашей форме. Текст для заполнителей будет взят из ярлыков полей модели.
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
Отличный вопрос. Я знаю о трех решениях:
Решение № 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'})
Решение № 3
Наконец, если вы работаете с модельной формой (в дополнение к двум предыдущим решениям), вы можете указать собственный виджет для поля, установив атрибут widgets
внутреннего класса Meta
.
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
widgets = {
'body': forms.Textarea(attrs={'cols': 80, 'rows': 20})
}
self.fields
, например: for field_name in self.fields: self.fields[field_name].widget.attrs.update({"placeholder": sth})
forms.TextInput
для объявленияattrs={'placeholder': 'Search'}
?