From 123c9f28a9a1b762b54addf32cc670dcb101fc9d Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Thu, 18 Jan 2018 10:01:21 +0000
Subject: [PATCH] Make the widgets lazy

---
 opentech/public/projects/widgets.py | 41 +++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 8 deletions(-)

diff --git a/opentech/public/projects/widgets.py b/opentech/public/projects/widgets.py
index a17bdac7f..8a60b8bd6 100644
--- a/opentech/public/projects/widgets.py
+++ b/opentech/public/projects/widgets.py
@@ -1,27 +1,52 @@
 import json
 
 from django import forms
+from django.utils.functional import LazyObject
 
 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):
-        widgets = [
-            OptionsWidget(
-                attrs={'id': cat.id, 'label_tag': cat.name},
-                choices=cat.options.all().values_list('id', 'value'),
-            )
-            for cat in Category.objects.all()
-        ]
-        kwargs['widgets'] = widgets
+        kwargs['widgets'] = list()
         super().__init__(*args, **kwargs)
+        self.widgets = LazyWidgets(OptionsWidget, Category)
+
 
     def decompress(self, value):
         data = json.loads(value)
-- 
GitLab