class ModelMultipleChoiceField
from django.forms import ModelMultipleChoiceField
A MultipleChoiceField whose choices are a model QuerySet.
Ancestors (MRO)
- ModelMultipleChoiceField
- ModelChoiceField
- ChoiceField
- Field
Attributes
Defined in | |
---|---|
creation_counter = 0
|
Field |
default_error_messages = {'list': 'Enter a list of values.', 'invalid_choice': 'Select a valid choice. %(value)s is not one of the available choices.', 'invalid_pk_value': '"%(pk)s" is not a valid value for a primary key.'}
|
ModelMultipleChoiceField |
default_error_messages = {'invalid_choice': 'Select a valid choice. That choice is not one of the available choices.'}
|
ModelChoiceField |
default_error_messages = {'invalid_choice': 'Select a valid choice. %(value)s is not one of the available choices.'}
|
ChoiceField |
default_error_messages = {'required': 'This field is required.'}
|
Field |
default_validators = []
|
Field |
empty_values = [None, '', [], (), {}]
|
Field |
Properties
def
choices():
¶
ModelChoiceField
Getter
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 self.iterator(self)
Setter
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
choices():
¶
ChoiceField
Getter
def _get_choices(self):
return self._choices
Setter
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
queryset():
¶
ModelChoiceField
Getter
def _get_queryset(self):
return self._queryset
Setter
def _set_queryset(self, queryset):
self._queryset = queryset
self.widget.choices = self.choices
Methods
def
_check_values(self, value):
¶
ModelMultipleChoiceField
Given a list of possible PK values, returns a QuerySet of the corresponding objects. Raises a ValidationError if a given value is invalid (not a valid PK, not in the queryset, etc.)
def _check_values(self, value):
"""
Given a list of possible PK values, returns a QuerySet of the
corresponding objects. Raises a ValidationError if a given value is
invalid (not a valid PK, not in the queryset, etc.)
"""
key = self.to_field_name or 'pk'
# deduplicate given values to avoid creating many querysets or
# requiring the database backend deduplicate efficiently.
try:
value = frozenset(value)
except TypeError:
# list of lists isn't hashable, for example
raise ValidationError(
self.error_messages['list'],
code='list',
)
for pk in value:
try:
self.queryset.filter(**{key: pk})
except (ValueError, TypeError):
raise ValidationError(
self.error_messages['invalid_pk_value'],
code='invalid_pk_value',
params={'pk': pk},
)
qs = self.queryset.filter(**{'%s__in' % key: value})
pks = set(force_text(getattr(o, key)) for o in qs)
for val in value:
if force_text(val) not in pks:
raise ValidationError(
self.error_messages['invalid_choice'],
code='invalid_choice',
params={'value': val},
)
return qs
def
bound_data(self, data, initial):
¶
Field
Return the value that should be shown for this field on render of a bound form, given the submitted POST data for the field and the initial data, if any. For most fields, this will simply be data; FileFields need to handle it a bit differently.
def bound_data(self, data, initial):
"""
Return the value that should be shown for this field on render of a
bound form, given the submitted POST data for the field and the initial
data, if any.
For most fields, this will simply be data; FileFields need to handle it
a bit differently.
"""
if self.disabled:
return initial
return data
def
clean(self, value):
¶
ModelMultipleChoiceField
def clean(self, value):
value = self.prepare_value(value)
if self.required and not value:
raise ValidationError(self.error_messages['required'], code='required')
elif not self.required and not value:
return self.queryset.none()
if not isinstance(value, (list, tuple)):
raise ValidationError(self.error_messages['list'], code='list')
qs = self._check_values(value)
# Since this overrides the inherited ModelChoiceField.clean
# we run custom validators here
self.run_validators(value)
return qs
Field
Validates the given value and returns its "cleaned" value as an appropriate Python object. Raises ValidationError for any errors.
def clean(self, value):
"""
Validates the given value and returns its "cleaned" value as an
appropriate Python object.
Raises ValidationError for any errors.
"""
value = self.to_python(value)
self.validate(value)
self.run_validators(value)
return value
def
get_bound_field(self, form, field_name):
¶
Field
Return a BoundField instance that will be used when accessing the form field in a template.
def get_bound_field(self, form, field_name):
"""
Return a BoundField instance that will be used when accessing the form
field in a template.
"""
return BoundField(form, self, field_name)
def
get_limit_choices_to(self):
¶
ModelChoiceField
Returns ``limit_choices_to`` for this form field. If it is a callable, it will be invoked and the result will be returned.
def get_limit_choices_to(self):
"""
Returns ``limit_choices_to`` for this form field.
If it is a callable, it will be invoked and the result will be
returned.
"""
if callable(self.limit_choices_to):
return self.limit_choices_to()
return self.limit_choices_to
def
has_changed(self, initial, data):
¶
ModelMultipleChoiceField
def has_changed(self, initial, data):
if self.disabled:
return False
if initial is None:
initial = []
if data is None:
data = []
if len(initial) != len(data):
return True
initial_set = set(force_text(value) for value in self.prepare_value(initial))
data_set = set(force_text(value) for value in data)
return data_set != initial_set
ModelChoiceField
def has_changed(self, initial, data):
if self.disabled:
return False
initial_value = initial if initial is not None else ''
data_value = data if data is not None else ''
return force_text(self.prepare_value(initial_value)) != force_text(data_value)
Field
Return True if data differs from initial.
def has_changed(self, initial, data):
"""
Return True if data differs from initial.
"""
# Always return False if the field is disabled since self.bound_data
# always uses the initial value in this case.
if self.disabled:
return False
try:
data = self.to_python(data)
if hasattr(self, '_coerce'):
return self._coerce(data) != self._coerce(initial)
except ValidationError:
return True
# For purposes of seeing whether something has changed, None is
# the same as an empty string, if the data or initial value we get
# is None, replace it with ''.
initial_value = initial if initial is not None else ''
data_value = data if data is not None else ''
return initial_value != data_value
def
label_from_instance(self, obj):
¶
ModelChoiceField
This method is used to convert objects into strings; it's used to generate the labels for the choices presented by this object. Subclasses can override this method to customize the display of the choices.
def label_from_instance(self, obj):
"""
This method is used to convert objects into strings; it's used to
generate the labels for the choices presented by this object. Subclasses
can override this method to customize the display of the choices.
"""
return force_text(obj)
def
prepare_value(self, value):
¶
ModelMultipleChoiceField
def prepare_value(self, value):
if (hasattr(value, '__iter__') and
not isinstance(value, six.text_type) and
not hasattr(value, '_meta')):
return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value]
return super(ModelMultipleChoiceField, self).prepare_value(value)
ModelChoiceField
def prepare_value(self, value):
if hasattr(value, '_meta'):
if self.to_field_name:
return value.serializable_value(self.to_field_name)
else:
return value.pk
return super(ModelChoiceField, self).prepare_value(value)
Field
def prepare_value(self, value):
return value
def
run_validators(self, value):
¶
Field
def run_validators(self, value):
if value in self.empty_values:
return
errors = []
for v in self.validators:
try:
v(value)
except ValidationError as e:
if hasattr(e, 'code') and e.code in self.error_messages:
e.message = self.error_messages[e.code]
errors.extend(e.error_list)
if errors:
raise ValidationError(errors)
def
to_python(self, value):
¶
ModelMultipleChoiceField
def to_python(self, value):
if not value:
return []
return list(self._check_values(value))
ModelChoiceField
def to_python(self, value):
if value in self.empty_values:
return None
try:
key = self.to_field_name or 'pk'
value = self.queryset.get(**{key: value})
except (ValueError, TypeError, self.queryset.model.DoesNotExist):
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
return value
ChoiceField
Returns a Unicode object.
def to_python(self, value):
"Returns a Unicode object."
if value in self.empty_values:
return ''
return force_text(value)
Field
def to_python(self, value):
return value
def
valid_value(self, value):
¶
ChoiceField
Check to see if the provided value is a valid choice
def valid_value(self, value):
"Check to see if the provided value is a valid choice"
text_value = force_text(value)
for k, v in self.choices:
if isinstance(v, (list, tuple)):
# This is an optgroup, so look inside the group for options
for k2, v2 in v:
if value == k2 or text_value == force_text(k2):
return True
else:
if value == k or text_value == force_text(k):
return True
return False
def
validate(self, value):
¶
ModelChoiceField
def validate(self, value):
return Field.validate(self, value)
ChoiceField
Validates that the input is in self.choices.
def validate(self, value):
"""
Validates that the input is in self.choices.
"""
super(ChoiceField, self).validate(value)
if value and not self.valid_value(value):
raise ValidationError(
self.error_messages['invalid_choice'],
code='invalid_choice',
params={'value': value},
)
Field
def validate(self, value):
if value in self.empty_values and self.required:
raise ValidationError(self.error_messages['required'], code='required')
def
widget_attrs(self, widget):
¶
Field
Given a Widget instance (*not* a Widget class), returns a dictionary of any HTML attributes that should be added to the Widget, based on this Field.
def widget_attrs(self, widget):
"""
Given a Widget instance (*not* a Widget class), returns a dictionary of
any HTML attributes that should be added to the Widget, based on this
Field.
"""
return {}