Newer
Older
import json
from django import forms
from opentech.apply.categories.models import Category
class LazyChoices:
def __init__(self, queryset, display):
self.queryset = queryset
self.display = display
def __iter__(self):
for choice in self.queryset.values_list(*self.display):
yield choice
class LazyWidgets:
def __init__(self, widget, model):
self.model = model
self.widget = widget
def __iter__(self):
for obj in self.model.objects.all():
yield self.widget(
attrs={'id': obj.id, 'label_tag': obj.name},
choices=LazyChoices(obj.options, ['id', 'value']),
)
class OptionsWidget(forms.CheckboxSelectMultiple):
template_name = 'projects/widgets/options_widget.html'
option_template_name = 'projects/widgets/options_option.html'
def __init__(self, *args, **kwargs):
choices = kwargs['choices']
super().__init__(*args, **kwargs)
self.choices = choices
class CategoriesWidget(forms.MultiWidget):
template_name = 'projects/widgets/categories_widget.html'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.widgets = LazyWidgets(OptionsWidget, Category)
def decompress(self, value):
data = json.loads(value)
return [
data.get(str(widget.attrs['id']), list()) for widget in self.widgets
]
def value_from_datadict(self, data, files, name):
data = {
widget.attrs['id']: widget.value_from_datadict(data, files, name + '_%s' % i)
for i, widget in enumerate(self.widgets)
}
return json.dumps(data)
def get_context(self, *args, **kwargs):
context = super().get_context(*args, **kwargs)
# Mutliwidget kills the wrap_label option when it is building the context
context['wrap_label'] = True
return context