chr*_*e31 16 django django-forms
我正在使用django-uniform并使用一些统一的功能,我正在寻找一种直接从表单声明添加css类的方法(对于独立小部件).
(作为奖励,这里我的可重复使用的只读自制mixin片段...)
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))
Run Code Online (Sandbox Code Playgroud)
我现在唯一的方法是在我的通用表单模板上添加一些javascript并手动添加类.
有什么明智的想法吗?
xj9*_*xj9 28
窗口小部件有一个attrs
关键字参数,它接受一个dict
可以定义它呈现的输入元素的属性.表单还有一些属性,您可以定义这些属性来更改Django显示表单的方式.请看以下示例:
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'}))
Run Code Online (Sandbox Code Playgroud)
这适用于任何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>
Run Code Online (Sandbox Code Playgroud)
然后,您可以随时向您正在使用的对象添加任意属性:
# 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)
Run Code Online (Sandbox Code Playgroud)
使用上下文中的表单呈现模板,并在模板中执行以下操作:
<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>
Run Code Online (Sandbox Code Playgroud)
无论你喜欢什么.
我发现这个片段可能是一个很好的答案:
这里是根据我的需求进行的调整(尚未测试,完成后我将编辑帖子):
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])
Run Code Online (Sandbox Code Playgroud)
如果您有更好的解决方案,无需调整所有 BoundField 类,我仍在倾听。
编辑:可能链接到 django 统一方式来处理必填字段,但它似乎不调用readonly_cssclass_adder
. 但我找到了另一个更简单的解决方案,我的 readOnly 小部件自动变成 readOnly ctrlHolder
这个补充是我目前最喜欢的回应:
编辑2:我最后选择的另一种方法是“覆盖”uni_form/field.html
不调用BoundField.label_tag的模板。所以我在这里检查了字段状态。
<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>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
20688 次 |
最近记录: |