将类添加到Django label_tag()输出

时间:2009-01-05 22:05:16

标签: python django forms newforms

我需要一些方法来为表单字段的label_tag()方法的输出添加一个class属性。

我看到有能力传入一个attrs字典,我已经在shell中测试了它,我可以做类似的事情:

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

我会在输出中看到class ='Foo',但是我没有看到从模板中添加attrs参数的方法 - 实际上,模板是专门针对它设计的,不是吗?

我的表单定义中是否有一种方法可以定义要在标签中显示的类?

在表单中,我可以执行以下操作为输入提供类

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

我只需要输出它的类。

8 个答案:

答案 0 :(得分:18)

技术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创建一个装饰器,它将通过适当设置 attrs 来调用它。然后你修补了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)    

答案 1 :(得分: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循环标记内工作。

答案 2 :(得分:8)

custom template tag似乎是解决方案。自定义过滤器也可以,但它可能不那么优雅。但是在这两种情况下你都需要回归自定义表单渲染。

如果这是一项非常重要的任务;我创建了一个Mixin,它允许我使用标签类注释表单字段,并使用这些类提供表单呈现方法。以便以下代码有效:

{{ form.as_table_with_label_classes }}

但是我想问一下;你真的需要一个标签上的课吗?我的意思是HTML设计明智。在那里添加类是绝对必要的吗?无法用一些CSS解决它:

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

我有时会使用jQuery来处理这种情况; 如果它有效,它将改进页面,但如果它没有,它将不会是一场灾难。并保持HTML源尽可能精简。

答案 3 :(得分:2)

有点太晚但遇到了类似的问题。希望这对你有所帮助。

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

答案 4 :(得分: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已经为此做了部分准备,但实际上并没有使用它。

答案 5 :(得分: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)

答案 6 :(得分: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,并在表单

中使用它

答案 7 :(得分:0)

我们还可以使用{{field.label}}和{{field.id_for_label}}

import matplotlib.pyplot as plt from matplotlib.patches import Polygon fig, ax = plt.subplots() ax.plot(x1, y1, 'k') ax.plot(x2, y2, 'k') verts = list(zip(x1+x2, y1+y2)) poly = Polygon(verts, facecolor='y') ax.add_patch(poly) plt.show()

以HTML格式呈现-

<label class="your_class_name" id="{{form.link.id_for_label}}">{{form.link.label}}</label>