2010-11-04 31 views
147

Lấy mẫu đơn giản này làm ví dụ.Làm cách nào để thêm trình giữ chỗ trên CharField ở Django?

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

này được kết xuất trong mẫu:

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

Tuy nhiên, tôi muốn thêm 'giữ chỗ' thuộc tính để lĩnh vực này với một giá trị của "Tìm kiếm" để các HTML sẽ giống như thế :

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

Tốt tôi muốn vượt qua giá trị giữ chỗ trong để CharField trong lớp hình thức thông qua một cuốn từ điển hoặc một cái gì đó như:

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

Cách tốt nhất để thực hiện điều này là gì?

Trả lời

212

Nhìn vào số widgets documentation. Về cơ bản nó sẽ trông giống như:

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

Viết thêm, vâng, nhưng sự tách biệt cho phép trừu tượng hóa các trường hợp phức tạp hơn.

Bạn cũng có thể khai báo một thuộc tính widgets chứa một ánh xạ <field name> => <widget instance> trực tiếp trên Meta của ModelForm sub-class của bạn.

+6

bạn sẽ làm điều này trên mô hình như thế nào? –

+0

bạn có cần phải chỉ định 'forms.TextInput' để thực hiện khai báo' attrs = {'placeholder': 'Search'} '? – JhovaniC

+1

@OvedD, tôi biết đây là cũ, nhưng hãy xem câu hỏi này: http://stackoverflow.com/questions/4341739/adding-an-attribute-to-the-input-tag-for-a-django-modelform-field – Simon

19

Bạn có thể sử dụng mã này để thêm attr giữ chỗ cho mọi trường TextInput trong biểu mẫu của bạn. Văn bản cho trình giữ chỗ sẽ được lấy từ nhãn trường mẫu.

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 
43

Đối với một ModelForm, bạn có thể sử dụng lớp Meta như sau:

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

Lưu ý rằng trong trường hợp này bạn không thể chỉ định trường cơ thể lớp. –

+0

Đây là phương pháp dễ nhất cho tôi - và thật tuyệt khi tất cả các thuộc tính khác (tức là bắt buộc) vẫn được tự động thêm mà không cần phải chỉ định chúng. – JxAxMxIxN

28

Các phương pháp khác đều tốt. Tuy nhiên, nếu bạn muốn không xác định lĩnh vực này (ví dụ đối với một số phương pháp năng động), bạn có thể sử dụng này:

def __init__(self, *args, **kwargs): 
    super(MyForm, self).__init__(*args, **kwargs) 
    self.fields['email'].widget.attrs['placeholder'] = self.fields['email'].label or '[email protected]' 

Nó cũng cho phép giữ chỗ để phụ thuộc vào các trường hợp cho ModelForms với ví dụ cụ thể.

+6

Điều này là rất tốt vì nó tránh phải lặp lại việc tạo các widget dài cho các đối tượng phức tạp hơn như 'ModelMultipleChoiceField'. Cảm ơn! – donturner

+1

Tinh thần tương tự: 'for f in MyCommentForm.base_fields.values ​​(): f.widget.attrs [" placeholder "] = f.label', nhưng tôi thích phương thức khởi tạo của bạn tốt hơn. – jozxyqk

+0

Đây là câu trả lời hay nhất. – kloddant

8

Câu hỏi hay. Có ba giải pháp tôi biết về:

Giải pháp # 1

Thay widget mặc định.

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

Giải pháp # 2

Tùy chỉnh widget mặc định. Nếu bạn đang sử dụng cùng một tiện ích mà trường thường sử dụng thì bạn chỉ có thể tùy chỉnh một tiện ích thay vì tạo ra một tiện ích hoàn toàn mới.

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

Giải pháp # 3

Cuối cùng, nếu bạn đang làm việc với một hình thức của model rồi (ngoài hai giải pháp trước), bạn có tùy chọn để chỉ định một widget tùy chỉnh cho một trường bằng cách đặt thuộc tính widgets của lớp bên trong Meta.

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

Tôi sắp viết một giải pháp như của bạn # 2. Tôi muốn thêm rằng bạn có thể áp dụng các hoạt động trên tất cả các trường bằng cách lặp qua 'self.fields', ví dụ:' cho field_name trong self.fields: self.fields [field_name] .widget.attrs.update ({" giữ chỗ ": sth})' –

+0

@AlbertoChiusole Có thể, nếu đó là những gì bạn muốn làm. Cảm ơn đã chỉ ra điều đó. –

Các vấn đề liên quan