Django의 CharField에 자리 표시자를 어떻게 추가합니까?


195

예를 들어 다음과 같은 매우 간단한 형태를 취하십시오

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

템플릿에서 렌더링됩니다.

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

그러나 HTML이 다음과 같이 보일 수 있도록 placeholder속성 값을이 필드 에 추가하려고합니다 Search.

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

바람직하게는 자리 표시 자 값을 CharField사전 또는 다음과 같은 형식 클래스를 통해 양식 클래스에 전달하고 싶습니다.

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

이것을 달성하는 가장 좋은 방법은 무엇입니까?

답변:


281

상기 봐 위젯 문서 . 기본적으로 다음과 같습니다.

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

더 많은 글을 쓸 것입니다. 그러나 분리를 통해 더 복잡한 경우를 더 잘 추상화 할 수 있습니다.

또한 선언 할 수 widgets포함하는 속성 <field name> => <widget instance>상의 직접 매핑을 Meta당신의 ModelForm하위 클래스를.


선언 forms.TextInput을 수행 하도록 지정해야 attrs={'placeholder': 'Search'}합니까?
JhovaniC

1
@OvedD, 나는 이것이 오래된 것을 알고 있지만이 질문을 참조하십시오 : stackoverflow.com/questions/4341739/…
NotSimon

1
@OvedD : 한 ModelForm으로이 작업을 수행하는 방법에 대한 내 대답을 참조
해미 다우 너

1
자리 표시자를 추가하기 위해 위젯을 지정해야한다는 것은 매우 어리 석습니다. 전체 위젯을 재정의하지 않고 위젯 속성을 편집 할 수 있어야합니다.
dspacejs

중국어의 경우 다음과 같은 선행 U가 필요합니다. { 'placeholder': u '搜索'}
shellbye

60

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

이 경우 클래스 본문에 필드를 지정할 수 없습니다.
Will S

이것은 나에게 가장 쉬운 방법이었고 다른 모든 속성 (예 : 필수)이 여전히 지정하지 않아도 자동으로 추가되는 것이 좋았습니다.
JxAxMxIxN

41

다른 방법은 모두 좋습니다. 그러나 필드를 지정하지 않으려면 (예 : 일부 동적 방법의 경우) 다음을 사용할 수 있습니다.

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의 인스턴스에 종속 될 수 있습니다.


7
이는보다 복잡한 객체에 대해 위젯의 긴 인스턴스화를 복제하지 않아도되기 때문에 좋습니다 ModelMultipleChoiceField. 감사!
donturner 2016 년

1
비슷한 정신 : for f in MyCommentForm.base_fields.values(): f.widget.attrs["placeholder"] = f.label,하지만 생성자 메서드가 더 좋습니다.
jozxyqk

21

이 코드를 사용하여 양식의 모든 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

19

좋은 질문입니다. 내가 아는 세 가지 솔루션이 있습니다.

해결책 # 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})
        }

1
나는 당신의 # 2로 해결책을 쓰려고했습니다. self.fields예를 들면 다음과 같이 반복하여 모든 필드에 작업을 적용 할 수 있다고 덧붙이고 싶습니다 .for field_name in self.fields: self.fields[field_name].widget.attrs.update({"placeholder": sth})
Alberto Chiusole

@AlbertoChiusole 네가 원한다면 할 수 있습니다. 지적 해 주셔서 감사합니다.
Dwayne Crooks

@DwayneCrooks cdosborn의 솔루션에 따라 # 3을 더 짧고 읽기 쉽 도록 업데이트하는 것이 좋습니다 .
Marian

1

자리 표시자를 재정의하려는 경우 위젯을 인스턴스화하는 방법을 알아야하는 것은 바람직하지 않습니다.

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

0

대부분의 경우 모든 자리 표시자가 내 모델에 정의 된 필드의 자세한 이름과 같도록하고 싶습니다.

내가 만든 양식에 쉽게 믹스 인을 추가했습니다.

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

-2

귀하의 방법을 살펴본 후이 방법을 사용하여 해결했습니다.

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

2
콘텐츠는 스택 오버플로에서 영어로 작성되어야합니다. 그 외에도 위의 질문에 대한 답변이 아니라 "나도"게시물 인 것 같습니다.
TylerH

더 자세한 내용을 추가하면 "나도"게시물에 문제가 없다고 말할 수 있습니다. 이 방법은 다른 방법과 어떻게 다릅니 까? 여기서 기술이나 필수 학습은 무엇입니까?
halfer
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.