Мне нужен способ добавить атрибут класса к выходным данным метода label_tag () для поля формы.
Я вижу, что есть возможность передать словарь attrs, и я протестировал его в оболочке, и я могу сделать что-то вроде:
for field in form:
print field.label_tag(attrs{'class':'Foo'})
Я увижу class = 'Foo' в моем выводе, но я не вижу способа добавить аргумент attrs из шаблона - на самом деле, шаблоны созданы специально для этого, не так ли?
Есть ли способ в моем определении формы определить класс, который будет отображаться в метке?
В форме я могу сделать следующее, чтобы дать входным данным класс
self.fields['some_field'].widget.attrs['class'] = 'Foo'
Мне просто нужно, чтобы он выводил и класс для.






настраиваемый тег шаблона кажется решением. Подойдет и собственный фильтр, хотя он может быть менее элегантным. Но в обоих случаях вам нужно будет вернуться к отрисовке пользовательской формы.
Если это задача большой важности; Я бы создал Mixin, который позволяет мне аннотировать поля формы с помощью классов меток и предоставляет методы рендеринга форм с использованием этих классов. Чтобы работал следующий код:
{{ form.as_table_with_label_classes }}
Но я хотел бы спросить; Вам действительно нужен класс в теге label? Я имею в виду HTML-дизайн. Обязательно там класс Добавлять? Разве это нельзя решить с помощью какого-нибудь CSS, например:
encapsulating_selector label {
some-attr: some-value;
}
Я иногда использую jQuery для таких случаев, когда; он улучшит страницу, если работает, но не будет катастрофой, если не. И старайтесь, чтобы исходный код HTML был как можно более компактным.
Я согласен с ответом номер один, с помощью 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 вызывает эту функцию без атрибутов:
label = bf.label_tag(label) or ''
Таким образом, кажется, что django частично готов к этому, но на самом деле он его не использует.
Как насчет добавления класса 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 в шаблоне.
Вы можете использовать {{form.title.auto_id}} вместо использования префикса "id_".
@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)
Техника 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.
В качестве альтернативы, я нашел один из наиболее интересных приемов: Добавление * в обязательные поля.
Вы создаете декоратор для 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 дает мне «AttributeError: объект SafeText не имеет атрибута label_tag» в Django 1.6. Вы не могли бы проверить?
Это из-за места. Удалите пробел при написании фильтра, до и после |
@AdamSilver Вы нашли для этого решение?
@Anuj Техника 1 с чем-то вроде {{form.password | label_with_classes: "col-sm-2 control-label"}} работает нормально.
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']}
Вам нужно изменить метод label_tag в классе BoundField и использовать его в форме
Это хорошо работает для обычных форм. Но я получаю ошибки, когда применяю то же исправление к ModelForms.
Слишком поздно, но столкнулся с похожей проблемой. Надеюсь, это тебе поможет.
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']
Я пытаюсь использовать этот метод, но ярлык не оформлен. Вы можете показать мне свой шаблон? В моем шаблоне есть это: {% для поля в форме%} {{field.label_tag}} {{field}} {% if field.help_text%} {{field.help_text | safe}} {% endif%} { % endfor%} Похоже, html_output не применяется ...
или он используется только при использовании as_table (), as_ul (), as_p ()?
@cwhisperer в вашем шаблоне вы должны использовать как form.as_two_col_layout, и код выполнит свою работу.
это отлично работает ... как сказать, что для myfield1 это текстовое поле?
мы также можем использовать {{field.label}} и {{field.id_for_label}}
<label class = "your_class_name" id = "{{form.link.id_for_label}}">{{form.link.label}}</label>
Визуализировать в HTML как-
<label class = "your_class_name" id = "id_name">Name</label>
Do you really need a class on the label tag?, да, если вы используете фреймворк типа bootstrap или foundation.