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

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

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

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



답변

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

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@address.nl'

또한 자리 표시자가 인스턴스가 지정된 ModelForms의 인스턴스에 종속 될 수 있습니다.


답변

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


답변

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

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


답변

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

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


답변

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

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

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