def __init__(self, choices=None, default=None, required=True, help_text=None, **kwargs): if choices is None: # no choices specified, so pick up the choice defined at the class level choices = self.choices if callable(choices): # Support of callable choices. Wrap the callable in an iterator so that we can # handle this consistently with ordinary choice lists; # however, the `choices` constructor kwarg as reported by deconstruct() should # remain as the callable choices_for_constructor = choices choices = CallableChoiceIterator(choices) else: # Cast as a list choices_for_constructor = choices = list(choices) # keep a copy of all kwargs (including our normalised choices list) for deconstruct() self._constructor_kwargs = kwargs.copy() self._constructor_kwargs['choices'] = choices_for_constructor if required is not True: self._constructor_kwargs['required'] = required if help_text is not None: self._constructor_kwargs['help_text'] = help_text # We will need to modify the choices list to insert a blank option, if there isn't # one already. We have to do this at render time in the case of callable choices - so rather # than having separate code paths for static vs dynamic lists, we'll _always_ pass a callable # to ChoiceField to perform this step at render time. # If we have a default choice and the field is required, we don't need to add a blank option. callable_choices = self.get_callable_choices(choices, blank_choice=not(default and required)) self.field = forms.ChoiceField(choices=callable_choices, required=required, help_text=help_text) super().__init__(default=default, **kwargs)
def model(self, model): if self._model != model: self._model = model self._fields = None # Clear cache self.widget.fields = CallableChoiceIterator( lambda: self._get_fields().items())
def model(self, model): self._model = model widget = self.widget widget.model = model widget.fields = CallableChoiceIterator( lambda: [(fname, field.verbose_name) for fname, field in self._get_fields().items()])
def _set_choices(self, value): # Setting choices also sets the choices on the widget. # choices can be any iterable, but we call list() on it because # it will be consumed more than once. if callable(value): value = CallableChoiceIterator(value) else: value = list(value) self._choices = self.widget.choices = value
def __init__( self, choices=None, default=None, required=True, help_text=None, widget=None, validators=(), **kwargs, ): self._required = required self._default = default if choices is None: # no choices specified, so pick up the choice defined at the class level choices = self.choices if callable(choices): # Support of callable choices. Wrap the callable in an iterator so that we can # handle this consistently with ordinary choice lists; # however, the `choices` constructor kwarg as reported by deconstruct() should # remain as the callable choices_for_constructor = choices choices = CallableChoiceIterator(choices) else: # Cast as a list choices_for_constructor = choices = list(choices) # keep a copy of all kwargs (including our normalised choices list) for deconstruct() # Note: we omit the `widget` kwarg, as widgets do not provide a serialization method # for migrations, and they are unlikely to be useful within the frozen ORM anyhow self._constructor_kwargs = kwargs.copy() self._constructor_kwargs["choices"] = choices_for_constructor if required is not True: self._constructor_kwargs["required"] = required if help_text is not None: self._constructor_kwargs["help_text"] = help_text # We will need to modify the choices list to insert a blank option, if there isn't # one already. We have to do this at render time in the case of callable choices - so rather # than having separate code paths for static vs dynamic lists, we'll _always_ pass a callable # to ChoiceField to perform this step at render time. callable_choices = self._get_callable_choices(choices) self.field = self.get_field( choices=callable_choices, required=required, help_text=help_text, validators=validators, widget=widget, ) super().__init__(default=default, **kwargs)
def __init__(self, *args, **kwargs): setvaluefield = kwargs.pop('setvaluefield') self.__choices = kwargs.pop('choices') if callable(self.__choices): self.__choices = CallableChoiceIterator(self.__choices) else: self.__choices = list(self.__choices) kwargs['choices'] = self._choices_slicer super().__init__(*args, **kwargs) self.widget.setvalues = {r[0]: (r[2], r[3]) for r in self.__choices} self.widget.setvaluefield = setvaluefield
def __init__(self, **kwargs): """Overload default choices handling to also accept a callable.""" choices = kwargs.get("choices") if callable(choices): kwargs["choices"] = CallableChoiceIterator(choices) super().__init__(**kwargs)
def model(self, model): self._model = model self.widget.ptypes = CallableChoiceIterator( lambda: [(pt.id, pt) for pt in self._get_ptypes()])
def model(self, model): self._model = model self.widget.rtypes = CallableChoiceIterator( lambda: [(rt.id, rt) for rt in self._get_rtypes()])
def model(self, model): # TODO: factorise ?? self._model = model self.widget.date_fields_options = CallableChoiceIterator( lambda: [(cf.id, cf) for cf in self._get_cfields()])
def model(self, model): self._model = model self.widget.fields = CallableChoiceIterator( lambda: [(cf.id, cf) for cf in self._get_cfields()])
def types(self, types): self._types = types self.widget.types = CallableChoiceIterator(self._get_types_options)
def choices(self) -> Iterable[Tuple[str, EntityCell]]: return CallableChoiceIterator(self._get_options)
def _refresh_widget(self): self.widget.regular_entry_choices = CallableChoiceIterator( self._get_regular_entries_options)
def _set_disables(self, value): if callable(value): value = CallableChoiceIterator(value) else: value = list(value) self._disables = self.widget.disables = value