Skip to content
Snippets Groups Projects
widgets.py 1.94 KiB
Newer Older
  • Learn to ignore specific revisions
  • import json
    
    from django import forms
    
    from opentech.apply.categories.models import Category
    
    
    
    Todd Dembrey's avatar
    Todd Dembrey committed
    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'
    
    
    Todd Dembrey's avatar
    Todd Dembrey committed
        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):
    
    Todd Dembrey's avatar
    Todd Dembrey committed
            kwargs['widgets'] = list()
    
            super().__init__(*args, **kwargs)
    
    Todd Dembrey's avatar
    Todd Dembrey committed
            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