import re import textwrap from django import forms from django.utils.safestring import mark_safe from django.contrib.admin.templatetags.admin_static import static class SpanWidget(forms.Widget): """ Renders a value wrapped in a tag. Requires use of specific form support. (see ReadonlyForm or ReadonlyModelForm) """ def __init__(self, *args, **kwargs): self.tag = kwargs.pop('tag', '') self.original = kwargs.pop('original', '') self.display = kwargs.pop('display', None) super(SpanWidget, self).__init__(*args, **kwargs) def render(self, name, value, attrs=None, renderer=None): final_attrs = self.build_attrs(attrs, extra_attrs={'name':name}) original = self.original or value display = original if self.display is None else self.display # Display icon if isinstance(original, bool): icon = static('admin/img/icon-%s.svg' % ('yes' if original else 'no',)) return mark_safe('%s' % (icon, display)) tag = self.tag[:-1] endtag = '/'.join((self.tag[0], self.tag[1:])) return mark_safe('%s%s >%s%s' % (tag, forms.utils.flatatt(final_attrs), display, endtag)) def value_from_datadict(self, data, files, name): return self.original def _has_changed(self, initial, data): return False class PaddingCheckboxSelectMultiple(forms.CheckboxSelectMultiple): """ Ugly hack to render this widget nicely on Django admin """ def __init__(self, padding, attrs=None, choices=()): super().__init__(attrs=attrs, choices=choices) self.padding = padding def render(self, *args, **kwargs): value = super().render(*args, **kwargs) value = re.sub(r'^