Fixed #5975 -- Gave `ModelChoiceField` and `ModelMultipleChoiceField` ability to specify custom error messages.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@6694 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
86ca11dd6d
commit
b2b6fc8e3c
|
@ -3,7 +3,7 @@ Helper functions for creating Form classes from Django models
|
||||||
and database field objects.
|
and database field objects.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from django.utils.translation import ugettext
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.encoding import smart_unicode
|
from django.utils.encoding import smart_unicode
|
||||||
from django.utils.datastructures import SortedDict
|
from django.utils.datastructures import SortedDict
|
||||||
|
|
||||||
|
@ -151,15 +151,20 @@ class ModelChoiceField(ChoiceField):
|
||||||
"""A ChoiceField whose choices are a model QuerySet."""
|
"""A ChoiceField whose choices are a model QuerySet."""
|
||||||
# This class is a subclass of ChoiceField for purity, but it doesn't
|
# This class is a subclass of ChoiceField for purity, but it doesn't
|
||||||
# actually use any of ChoiceField's implementation.
|
# actually use any of ChoiceField's implementation.
|
||||||
|
default_error_messages = {
|
||||||
|
'invalid_choice': _(u'Select a valid choice. That choice is not one of'
|
||||||
|
u' the available choices.'),
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, queryset, empty_label=u"---------", cache_choices=False,
|
def __init__(self, queryset, empty_label=u"---------", cache_choices=False,
|
||||||
required=True, widget=Select, label=None, initial=None,
|
required=True, widget=Select, label=None, initial=None,
|
||||||
help_text=None):
|
help_text=None, *args, **kwargs):
|
||||||
self.empty_label = empty_label
|
self.empty_label = empty_label
|
||||||
self.cache_choices = cache_choices
|
self.cache_choices = cache_choices
|
||||||
# Call Field instead of ChoiceField __init__() because we don't need
|
# Call Field instead of ChoiceField __init__() because we don't need
|
||||||
# ChoiceField.__init__().
|
# ChoiceField.__init__().
|
||||||
Field.__init__(self, required, widget, label, initial, help_text)
|
Field.__init__(self, required, widget, label, initial, help_text,
|
||||||
|
*args, **kwargs)
|
||||||
self.queryset = queryset
|
self.queryset = queryset
|
||||||
|
|
||||||
def _get_queryset(self):
|
def _get_queryset(self):
|
||||||
|
@ -200,36 +205,38 @@ class ModelChoiceField(ChoiceField):
|
||||||
try:
|
try:
|
||||||
value = self.queryset.get(pk=value)
|
value = self.queryset.get(pk=value)
|
||||||
except self.queryset.model.DoesNotExist:
|
except self.queryset.model.DoesNotExist:
|
||||||
raise ValidationError(ugettext(u'Select a valid choice. That'
|
raise ValidationError(self.error_messages['invalid_choice'])
|
||||||
u' choice is not one of the'
|
|
||||||
u' available choices.'))
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
class ModelMultipleChoiceField(ModelChoiceField):
|
class ModelMultipleChoiceField(ModelChoiceField):
|
||||||
"""A MultipleChoiceField whose choices are a model QuerySet."""
|
"""A MultipleChoiceField whose choices are a model QuerySet."""
|
||||||
hidden_widget = MultipleHiddenInput
|
hidden_widget = MultipleHiddenInput
|
||||||
|
default_error_messages = {
|
||||||
|
'list': _(u'Enter a list of values.'),
|
||||||
|
'invalid_choice': _(u'Select a valid choice. %s is not one of the'
|
||||||
|
u' available choices.'),
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, queryset, cache_choices=False, required=True,
|
def __init__(self, queryset, cache_choices=False, required=True,
|
||||||
widget=SelectMultiple, label=None, initial=None,
|
widget=SelectMultiple, label=None, initial=None,
|
||||||
help_text=None):
|
help_text=None, *args, **kwargs):
|
||||||
super(ModelMultipleChoiceField, self).__init__(queryset, None,
|
super(ModelMultipleChoiceField, self).__init__(queryset, None,
|
||||||
cache_choices, required, widget, label, initial, help_text)
|
cache_choices, required, widget, label, initial, help_text,
|
||||||
|
*args, **kwargs)
|
||||||
|
|
||||||
def clean(self, value):
|
def clean(self, value):
|
||||||
if self.required and not value:
|
if self.required and not value:
|
||||||
raise ValidationError(ugettext(u'This field is required.'))
|
raise ValidationError(self.error_messages['required'])
|
||||||
elif not self.required and not value:
|
elif not self.required and not value:
|
||||||
return []
|
return []
|
||||||
if not isinstance(value, (list, tuple)):
|
if not isinstance(value, (list, tuple)):
|
||||||
raise ValidationError(ugettext(u'Enter a list of values.'))
|
raise ValidationError(self.error_messages['list'])
|
||||||
final_values = []
|
final_values = []
|
||||||
for val in value:
|
for val in value:
|
||||||
try:
|
try:
|
||||||
obj = self.queryset.get(pk=val)
|
obj = self.queryset.get(pk=val)
|
||||||
except self.queryset.model.DoesNotExist:
|
except self.queryset.model.DoesNotExist:
|
||||||
raise ValidationError(ugettext(u'Select a valid choice. %s is'
|
raise ValidationError(self.error_messages['invalid_choice'] % val)
|
||||||
u' not one of the available'
|
|
||||||
u' choices.') % val)
|
|
||||||
else:
|
else:
|
||||||
final_values.append(obj)
|
final_values.append(obj)
|
||||||
return final_values
|
return final_values
|
||||||
|
|
|
@ -312,4 +312,49 @@ ValidationError: [u'REQUIRED']
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
ValidationError: [u'INVALID IP ADDRESS']
|
ValidationError: [u'INVALID IP ADDRESS']
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Create choices for the model choice field tests below.
|
||||||
|
|
||||||
|
>>> from regressiontests.forms.models import ChoiceModel
|
||||||
|
>>> ChoiceModel.objects.create(pk=1, name='a')
|
||||||
|
<ChoiceModel: ChoiceModel object>
|
||||||
|
>>> ChoiceModel.objects.create(pk=2, name='b')
|
||||||
|
<ChoiceModel: ChoiceModel object>
|
||||||
|
>>> ChoiceModel.objects.create(pk=3, name='c')
|
||||||
|
<ChoiceModel: ChoiceModel object>
|
||||||
|
|
||||||
|
# ModelChoiceField ############################################################
|
||||||
|
|
||||||
|
>>> e = {'required': 'REQUIRED'}
|
||||||
|
>>> e['invalid_choice'] = 'INVALID CHOICE'
|
||||||
|
>>> f = ModelChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e)
|
||||||
|
>>> f.clean('')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'REQUIRED']
|
||||||
|
>>> f.clean('4')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'INVALID CHOICE']
|
||||||
|
|
||||||
|
# ModelMultipleChoiceField ####################################################
|
||||||
|
|
||||||
|
>>> e = {'required': 'REQUIRED'}
|
||||||
|
>>> e['invalid_choice'] = '%s IS INVALID CHOICE'
|
||||||
|
>>> e['list'] = 'NOT A LIST OF VALUES'
|
||||||
|
>>> f = ModelMultipleChoiceField(queryset=ChoiceModel.objects.all(), error_messages=e)
|
||||||
|
>>> f.clean('')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'REQUIRED']
|
||||||
|
>>> f.clean('3')
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'NOT A LIST OF VALUES']
|
||||||
|
>>> f.clean(['4'])
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValidationError: [u'4 IS INVALID CHOICE']
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -10,6 +10,10 @@ class Defaults(models.Model):
|
||||||
def_date = models.DateField(default = datetime.date(1980, 1, 1))
|
def_date = models.DateField(default = datetime.date(1980, 1, 1))
|
||||||
value = models.IntegerField(default=42)
|
value = models.IntegerField(default=42)
|
||||||
|
|
||||||
|
class ChoiceModel(models.Model):
|
||||||
|
"""For ModelChoiceField and ModelMultipleChoiceField tests."""
|
||||||
|
name = models.CharField(max_length=10)
|
||||||
|
|
||||||
__test__ = {'API_TESTS': """
|
__test__ = {'API_TESTS': """
|
||||||
>>> from django.newforms import form_for_model, form_for_instance
|
>>> from django.newforms import form_for_model, form_for_instance
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue