我正在使用django-uniform并使用一些统一功能,我正在寻找一种直接从表单声明中添加css类的方法(对于独立窗口小部件)。
(作为奖励,这里是我可重复使用的只读家庭自制混合片段……)
from django import forms def _get_cleaner(form, field): def clean_field(): return getattr(form.instance, field, None) return clean_field class UniformROMixin(forms.BaseForm): """ UniformROMixin, inherits to turn some fields read only - read_only = list of field names. """ def __init__(self, *args, **kwargs): super(UniformROMixin, self).__init__(*args, **kwargs) if hasattr(self, "read_only"): if self.instance and self.instance.pk: for field in self.read_only: self.fields[field].widget.attrs['readonly'] = True self.fields[field].widget.attrs['class'] += "readOnly" # here I would like to set css class of the label # created from the self.fields[field].label string setattr(self, "clean_" + field, _get_cleaner(self, field))
目前,我唯一的方法是在通用表单模板上添加一些javascript并手动添加类。
我发现此片段可能是一个不错的答案:
如何将CSS类和“ *”添加到必填字段的标签
“ *”
这是适应我需要的内容(未经测试,完成后我将对其进行编辑):
from django.utils.html import escape def readonly_cssclass_adder(bound_field, label_content, label_attrs): if 'readonly' in bound_field.field.widget.attrs: if 'class' in attrs: label_attrs['class'] += " readOnly" else: label_attrs['class'] = "readOnly" return label_content, label_attrs def add_required_label_tag(original_function, tweak_foos=None): if not tweak_foos: return original_function def required_label_tag(self, contents=None, attrs=None): contents = contents or escape(self.label) if attrs is None: attrs = {} for foo in tweak_foos: contents, attrs = foo(self, contents, attrs) return original_function(self, contents, attrs) return required_label_tag def decorate_bound_field(): from django.forms.forms import BoundField BoundField.label_tag = add_required_label_tag(BoundField.label_tag, tweak_foos=[readonly_cssclass_adder])
如果您有一个更好的解决方案,而不需要调整所有的BoundField类,我仍在听。
编辑:可能链接到Django统一方式来处理必填字段,但似乎不调用readonly_cssclass_adder。但是我找到了另一个更简单的解决方案,我的readOnly小部件会自动变为readOnly ctrlHolder
此添加是我目前最喜欢的回复:
编辑2:最后我选择的另一种方法是“覆盖” uni_form/field.html不调用BoundField.label_tag 的模板。所以我在这里检查了字段状态。
uni_form/field.html
<label for="{{ field.auto_id }}"{% if field.field.required %} class="requiredField{% if field.widget.attrs.readonly %} readOnlyLabel{% endif %}" {% else %}{% if field.widget.attrs.readonly %}class="readOnlyLabel"{% endif %}{% endif %}> {{ field.label|safe }}{% if field.field.required %}<span class="asteriskField">*</span>{% endif %} </label>
窗口小部件的attrs关键字参数带有dict,可以定义其呈现的输入元素的属性。表单还具有一些可以定义的属性,以更改Django显示表单的方式。请看以下示例:
attrs
dict,
class MyForm(forms.Form): error_css_class = 'error' required_css_class = 'required' my_field = forms.CharField(max_length=10, widget=forms.TextInput(attrs={'id': 'my_field', 'class': 'my_class'}))
这适用于任何Widget课程。不幸的是,没有一种简单的方法可以改变Django渲染标签的方式{{ field }}。幸运的是,你在模板中使用了表单对象:
<form> {% for field in form %} <label class="my_class" for="{{ field.name }}">{{ field.label }}</label> {{ field }} {% endfor %} <button type="submit">Submit</button> </form>
再说一遍,你始终可以向正在使用的对象添加任意属性:
# In a view... form = MyForm() form.label_classes = ('class_a', 'class_b', ) # Or by hijacking ```__init__``` class MyForm(forms.Form): def __init__(self, *args, **kwargs): self.my_field = forms.CharField(max_length=10, widget=forms.TextInput(attrs={'id': 'my_field', 'class': 'my_class'})) self.my_field.label_classes = ('class_a', 'class_b', ) super(MyForm, self).__init__(*args, **kwargs)
在上下文中使用表单呈现模板,你可以在模板中执行以下操作:
<form> {% for field in form %} <label class="{% for class in field.label_classes %}{{ class }} {% endfor %}" for="{{ field.name }}">{{ field.label }}</label> {{ field }} {% endfor %} <button type="submit">Submit</button> </form>