2009-01-05 114 views
23

我需要某種方法將類屬性添加到表單字段的label_tag()方法的輸出中。將類添加到Django label_tag()輸出

我看到有處於ATTRS字典傳遞能力,我在外殼測試它,我可以這樣做:

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

我會看到類=「富」我輸出,但我沒有看到從模板中添加attrs參數的方法 - 實際上,模板是專門針對該模板設計的,不是嗎?

在我的表單定義中是否有一種方法來定義要在標籤中顯示的類?

在形式,我可以做以下給輸入一個類

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

我只是需要把它輸出的類爲好。

回答

8

A custom template tag似乎是解決方案。自定義過濾器也可以,雖然它可能不太優雅。但在這兩種情況下,您都需要回到自定義表單呈現。

如果這是一個高度重要的任務;我創建了一個Mixin,它允許我使用標籤類註釋表單域,並使用這些類提供表單呈現方法。因此,下面的代碼工作:

{{ form.as_table_with_label_classes }} 

但我想問一下;你真的需要標籤標籤上的課嗎?我的意思是HTML設計。 加上這裏的班是絕對必要的嗎?無法將其與像一些CSS來解決:

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

我有時用jQuery這樣的情況下, 它會改善頁面,但它不會是一個災難,如果它不。並儘可能保持HTML源代碼的精簡。

+34

`你真的需要標籤標籤上的類?`,是的,如果你使用像引導程序或基礎的框架。 – vikki 2013-11-04 15:21:51

1

我同意第一個答案,用CSS就可以完成,但是。 這是在Django源代碼中的共鳴點是什麼?

在django.forms.forms.py有這個定義,顯示有代碼的標籤顯示ATTRS:

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

_html_output調用此功能,無需ATTRS:

label = bf.label_tag(label) or '' 

如此看來django已經部分準備好了,但實際上並沒有使用它。

11

如何添加CSS類到窗體字段中forms.py,如:

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

話,我只是做模板以下幾點:

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

當然這些都可以很容易被修改以在模板中的for循環標籤內工作。

+9

您可以使用{{form.title.auto_id}}而不是假設「id_」前綴。 – matthewwithanm 2011-01-21 15:51:56

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

技術1

我再跟另一個答案的說法,一個過濾器將是「不太優雅。」正如你所看到的,它的確非常優雅。

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

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

在模板中使用這只是優雅:

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

技術2

或者,更有趣的技術,我發現之一是:Adding * to required fields

您爲BoundField.label_tag創建了一個裝飾器,它將使用設置適當的來調用它。然後你可以修補BoundField,以便調用BoundField.label_tag調用裝飾函數。

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

技術1給我「AttributeError:'SafeText'對象沒有屬性'label_tag'」與Django 1.6。你能檢查一下嗎? – 2013-11-24 05:53:53

+0

這是因爲一個空間。在|之前和之後寫入過濾器時刪除空格 – tilaprimera 2015-01-21 10:07:03

+0

@AdamSilver您是否找到解決方案? – Anuj 2016-03-04 04:12:47

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

您需要的BoundField類改變方法label_tag,並用它在形式上

1

有點晚,但碰到類似的問題就來了。希望這可以幫助你。

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