Created
October 11, 2010 09:09
-
-
Save ojii/620248 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from django.forms.fields import ChoiceField | |
| from django.forms.models import ModelChoiceField, ModelMultipleChoiceField | |
| class CachedModelChoiceIterator(object): | |
| def __init__(self, field): | |
| self.field = field | |
| self.queryset = field.queryset | |
| self.model = field.queryset.model | |
| def __iter__(self): | |
| if self.field.empty_label is not None: | |
| yield (u"", self.field.empty_label) | |
| if self.model not in CachedModelChoiceField.__cache__: | |
| CachedModelChoiceField.__cache__[self.model] = [ | |
| self.choice(obj) for obj in self.queryset.all() | |
| ] | |
| for choice in CachedModelChoiceField.__cache__[self.model]: | |
| yield choice | |
| def __len__(self): | |
| return len(self.queryset) | |
| def choice(self, obj): | |
| return (self.field.prepare_value(obj), self.field.label_from_instance(obj)) | |
| class CachedModelChoiceField(ModelChoiceField): | |
| __cache__ = {} | |
| def _get_choices(self): | |
| # If self._choices is set, then somebody must have manually set | |
| # the property self.choices. In this case, just return self._choices. | |
| if hasattr(self, '_choices'): | |
| return self._choices | |
| # Otherwise, execute the QuerySet in self.queryset to determine the | |
| # choices dynamically. Return a fresh ModelChoiceIterator that has not been | |
| # consumed. Note that we're instantiating a new ModelChoiceIterator *each* | |
| # time _get_choices() is called (and, thus, each time self.choices is | |
| # accessed) so that we can ensure the QuerySet has not been consumed. This | |
| # construct might look complicated but it allows for lazy evaluation of | |
| # the queryset. | |
| return CachedModelChoiceIterator(self) | |
| choices = property(_get_choices, ChoiceField._set_choices) | |
| class CachedModelMultipleChoiceField(CachedModelChoiceField , ModelMultipleChoiceField): pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment