以这个非常简单的形式为例:

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

这将在模板中呈现:

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

然而,我想在这个字段中添加一个搜索值的占位符属性,这样HTML看起来就像这样:

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

最好是我想通过字典或类似的东西在表单类中传递占位符值到CharField:

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

实现这一目标的最佳方式是什么?


当前回答

看了你的方法后,我用了这个方法来解决它。

class Register(forms.Form):
    username = forms.CharField(label='用户名', max_length=32)
    email = forms.EmailField(label='邮箱', max_length=64)
    password = forms.CharField(label="密码", min_length=6, max_length=16)
    captcha = forms.CharField(label="验证码", max_length=4)

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    for field_name in self.fields:
        field = self.fields.get(field_name)
        self.fields[field_name].widget.attrs.update({
            "placeholder": field.label,
            'class': "input-control"
        })

其他回答

其他方法都很好。然而,如果你不喜欢指定字段(例如对于一些动态方法),你可以使用这个:

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'

它还允许占位符依赖于指定实例的ModelForms实例。

大多数时候,我只是希望所有占位符都等于在模型中定义的字段的详细名称

我添加了一个mixin,可以很容易地对我创建的任何表单进行此操作,

class ProductForm(PlaceholderMixin, ModelForm):
    class Meta:
        model = Product
        fields = ('name', 'description', 'location', 'store')

And

class PlaceholderMixin:
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        field_names = [field_name for field_name, _ in self.fields.items()]
        for field_name in field_names:
            field = self.fields.get(field_name)
            field.widget.attrs.update({'placeholder': field.label})

对于一个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'}),
        }

好问题。我知道有三个解决方案:

解决方案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属性来为字段指定自定义小部件。

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

查看小部件文档。基本上看起来是这样的:

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

更多的写作,是的,但分离允许更好地抽象更复杂的情况。

您还可以直接在ModelForm子类的Meta上声明一个包含<字段名> => <widget实例>映射的widgets属性。