2009-01-05 34 views
23

Tôi cần một số cách để thêm thuộc tính lớp vào đầu ra của phương thức label_tag() cho trường biểu mẫu.Thêm lớp vào Django label_tag() output

tôi thấy rằng có khả năng vượt qua trong một cuốn từ điển attrs và tôi đã thử nghiệm nó trong vỏ và tôi có thể làm điều gì đó như:

for field in form: 
    print field.label_tag(attrs{'class':'Foo'}) 

tôi sẽ thấy những class = 'Foo' trong tôi đầu ra, nhưng tôi không thấy một cách để thêm một đối số attrs từ mẫu - trong thực tế, các mẫu được thiết kế đặc biệt chống lại điều đó, không?

Có cách nào trong định nghĩa biểu mẫu của tôi để xác định lớp được hiển thị trong nhãn không?

Trong hình thức, tôi có thể làm như sau để cung cấp cho các đầu vào một lớp

self.fields['some_field'].widget.attrs['class'] = 'Foo' 

Tôi chỉ cần có nó đầu ra lớp cho là tốt.

Trả lời

8

A custom template tag có vẻ là giải pháp. Một bộ lọc tùy chỉnh cũng sẽ làm, mặc dù nó có thể ít thanh lịch hơn. Nhưng bạn sẽ cần phải quay trở lại để hiển thị biểu mẫu tùy chỉnh trong cả hai trường hợp.

Nếu đây là nhiệm vụ có tầm quan trọng cao; Tôi muốn tạo một Mixin cho phép tôi chú thích các trường biểu mẫu với các lớp nhãn và cung cấp các phương thức kết xuất biểu mẫu bằng cách sử dụng các lớp đó. Để mã sau hoạt động:

{{ form.as_table_with_label_classes }} 

Nhưng tôi muốn hỏi; Bạn có thực sự cần một lớp học trên thẻ nhãn không? Tôi có nghĩa là thiết kế HTML khôn ngoan. Hoàn toàn cần thiết để thêm một lớp học trong đó? Không thể giải quyết được bằng một số CSS như:

encapsulating_selector label { 
    some-attr: some-value; 
} 

Đôi khi tôi sử dụng jQuery cho những trường hợp như vậy; nó sẽ cải thiện trang nếu nó hoạt động, nhưng nó sẽ không phải là một thảm họa nếu nó không. Và giữ cho nguồn HTML càng gọn gàng càng tốt.

+34

'Bạn có thực sự cần một lớp trên thẻ nhãn không?', Có nếu bạn đang sử dụng một khung như bootstrap hoặc nền tảng. – vikki

1

Tôi đồng ý với câu trả lời số một, với css điều này có thể được thực hiện, nhưng. Âm vang cho điều này là gì trong nguồn django?

Trong django.forms.forms.py có định nghĩa này cho thấy có mã để hiển thị attrs trong nhãn:

class BoundField(StrAndUnicode): 
# .... 
def label_tag(self, contents=None, attrs=None): 
    contents = u'<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, unicode(contents)) 

nhưng _html_output cuộc gọi chức năng này mà không cần attrs:

label = bf.label_tag(label) or '' 

Vì vậy, có vẻ như rằng django được chuẩn bị một phần cho điều này nhưng thực ra nó không sử dụng nó.

11

Làm thế nào về việc thêm các lớp CSS cho trường mẫu trong forms.py, như:

class MyForm(forms.Form): 
    title = forms.CharField(widget=forms.TextInput(attrs={'class': 'foo'})) 

sau đó tôi chỉ làm như sau trong mẫu:

<label for="id_{{form.title.name}}" class="bar"> 
    {{ form.title }} 
</label> 

Tất nhiên điều này có thể dễ dàng được sửa đổi để làm việc trong một thẻ vòng lặp for trong mẫu.

+9

Bạn có thể sử dụng {{form.title.auto_id}} thay vì giả sử tiền tố "id_". – matthewwithanm

0
@register.simple_tag 
def advanced_label_tag(field): 
    """ Return form field label html marked to fill by `*` """ 
    classes = [] 
    attrs = {} 
    contents = force_unicode(escape(field.label)) 

    if field.field.required: 
     classes.append(u'required') 
     contents = force_unicode('%s <span>*</span>'%escape(field.label)) 

    if classes: 
     attrs['class'] = u' '.join(classes) 

    return field.label_tag(contents=contents, attrs=attrs) 
16

Kỹ thuật 1

Tôi không đồng ý với khẳng định của câu trả lời khác rằng một bộ lọc sẽ là "ít thanh lịch." Như bạn có thể thấy, nó thực sự rất tao nhã.

@register.filter(is_safe=True) 
def label_with_classes(value, arg): 

    return value.label_tag(attrs={'class': arg}) 

Sử dụng điều này trong một mẫu chỉ như tao nhã:

{{ form.my_field|label_with_classes:"class1 class2"}} 

Kỹ thuật 2

Ngoài ra, một trong những kỹ thuật thú vị hơn tôi đã tìm thấy là: Adding * to required fields.

Bạn tạo một trình trang trí cho BoundField.label_tag sẽ gọi nó với attrs được đặt thích hợp. Sau đó, bạn vá lỗi BoundField để gọi BoundField.label_tag gọi hàm được trang trí.

from django.forms.forms import BoundField 

def add_control_label(f): 
    def control_label_tag(self, contents=None, attrs=None): 
     if attrs is None: attrs = {} 
     attrs['class'] = 'control-label' 
     return f(self, contents, attrs) 
    return control_label_tag 

BoundField.label_tag = add_control_label(BoundField.label_tag)  
+4

Kỹ thuật 1 cho tôi đối tượng "AttributeError: 'SafeText' không có thuộc tính 'label_tag'" với Django 1.6. Bạn vui lòng kiểm tra? –

+0

Đó là vì một không gian. Xóa không gian khi bạn viết bộ lọc, trước và sau | – tilaprimera

+0

@AdamSilver Bạn đã tìm thấy giải pháp cho điều này? – Anuj

0
class CustomBoundField(BoundField): 
    def label_tag(self, contents=None, attrs=None): 
     if self.field.required: 
      attrs = {'class': 'required'} 
     return super(CustomBoundField, self).label_tag(contents, attrs) 

class ImportViewerForm(forms.Form): 
    url = fields.URLField(widget=forms.TextInput(attrs={'class': 'vTextField'})) 
    type = fields.ChoiceField(choices=[('o', 'Organisation'), ('p', 'Program')], widget=forms.RadioSelect, 
           help_text='Url contain infornation about this type') 
    source = fields.ChoiceField(choices=[('h', 'hodex'), ('s', 'studyfinder')], initial='h', widget=forms.RadioSelect) 

    def __getitem__(self, name): 
     "Returns a BoundField with the given name." 
     try: 
      field = self.fields[name] 
     except KeyError: 
      raise KeyError('Key %r not found in Form' % name) 
     return CustomBoundField(self, field, name) 

class Media: 
    css = {'all': [settings.STATIC_URL + 'admin/css/forms.css']} 

Bạn cần thay đổi phương pháp label_tag trong lớp BoundField, và sử dụng nó ở dạng

+0

Tính năng này hoạt động tốt cho các biểu mẫu bình thường. Nhưng tôi nhận được lỗi khi tôi áp dụng cùng một sửa chữa cho ModelForms. –

1

Một chút quá muộn nhưng tình cờ gặp một vấn đề tương tự. Hy vọng điều này sẽ giúp bạn.

class MyForm(forms.ModelForm): 

    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.fields['myfield1'].widget.attrs.update(
      {'class': 'form-control'}) 
     self.fields['myfield2'].widget.attrs.update(
      {'class': 'form-control'}) 

    def as_two_col_layout(self): 

     return self._html_output(
      normal_row='<div class="form-group"><span class="col-xs-2">%(label)s</span> <div class="col-xs-10">%(field)s%(help_text)s</div></div>', 
      error_row='%s', 
      row_ender='</div>', 
      help_text_html=' <span class="helptext">%s</span>', 
      errors_on_separate_row=True) 

    class Meta: 

     model = mymodel 
     fields = ['myfield1', 'myfield2'] 
+0

Tôi cố gắng sử dụng phương pháp này, nhưng nhãn không được tạo kiểu. Bạn có thể chỉ cho tôi mẫu của bạn không? Tôi có điều này trong mẫu của tôi: {% cho trường theo dạng%} {{field.label_tag}} {{field}} {% if field.help_text%} {{field.help_text | safe}} {% endif%} {% endfor%} Dường như html_output không được áp dụng ... – cwhisperer

+0

hoặc nó chỉ được sử dụng khi sử dụng bởi as_table(), as_ul(), as_p()? – cwhisperer

+1

@cwhisperer trong mẫu của bạn mà bạn đã sử dụng dưới dạng form.as_two_col_layout và mã sẽ thực hiện công việc. –

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