ChatGPT解决这个技术问题 Extra ChatGPT

如何在 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')

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


o
orokusaki

查看 widgets documentation。基本上它看起来像:

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

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

您还可以直接在 ModelForm 子类的 Meta 上声明包含 <field name> => <widget instance> 映射的 widgets 属性。


@OvedD,我知道这是旧的,但看到这个问题:stackoverflow.com/questions/4341739/…
@OvedD:请参阅我的答案,了解如何使用 ModelForm 执行此操作
您必须指定一个小部件才能添加占位符,这非常愚蠢。您应该能够在不覆盖整个小部件的情况下编辑小部件属性...
对于中文,你需要像这样的前面的 u:{'placeholder': u'Search'}
@shellbye 这仅在 Python2 中是正确的,您可能不应该在 2017 年使用它,而且现在绝对不应该使用它。
H
Hamish Downer

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

请注意,在这种情况下,您不能在类主体中指定字段。
这对我来说是最简单的方法 - 很高兴所有其他属性(即必需的)仍然自动添加而无需我指定它们。
M
Mark

其他方法都很好。但是,如果您不想指定字段(例如对于某些动态方法),您可以使用:

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 的实例。


这很好,因为它避免了为更复杂的对象(例如 ModelMultipleChoiceField)重复冗长的小部件实例化。谢谢!
类似的精神:for f in MyCommentForm.base_fields.values(): f.widget.attrs["placeholder"] = f.label,但我更喜欢你的构造方法。
D
Dwayne Crooks

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

解决方案#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})
        }

我正要写一个解决方案,就像你的 #2 一样。我想补充一点,您可以通过遍历 self.fields 对所有字段应用操作,例如:for field_name in self.fields: self.fields[field_name].widget.attrs.update({"placeholder": sth})
@AlbertoChiusole 是的,如果您想这样做,您可以。感谢您指出。
@DwayneCrooks 我建议您按照 cdosborn's solution 更新您的 #3,因为它更短且更具可读性。
S
Sheridan

您可以使用此代码为表单中的每个 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

E
Ehsan88

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

我添加了一个 mixin 可以轻松地对我创建的任何表单执行此操作,

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

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

c
cdosborn

当您只想覆盖其占位符时,必须知道如何实例化一个小部件是不可取的。

    q = forms.CharField(label='search')
    ...
    q.widget.attrs['placeholder'] = "Search"

R
Ramlakhan Kevat
class FormClass(forms.ModelForm):
    class Meta:
        model = Book
        fields = '__all__'
        widgets = {
            'field_name': forms.TextInput(attrs={'placeholder': 'Type placeholder text here..'}),
        }

感谢您的贡献。您能否添加一些解释,以帮助用户深入理解?
l
lber l

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

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

请注意,Stack Overflow 上的内容必须是英文的。除此之外,这似乎是一个“我也是”的帖子,而不是对上述问题的回答。
如果他们添加更多细节,我会说“我也是”的帖子是可以的。这种方法与其他方法有何不同?这里的技术或基本学习是什么?