1
0
mirror of https://github.com/django/django.git synced 2025-06-05 03:29:12 +00:00

Fixed #4787, #5913 -- Updating the queryset on a ModelChoiceField or ModelMultipleChoiceField now updates its widget's choices. The clean methods for ModelChoiceField and ModelMultipleChoiceField were changed to only allow choices in the specified queryset (instead of allowing all choices returned by the queryset model's default manager).

git-svn-id: http://code.djangoproject.com/svn/django/trunk@6670 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Gary Wilson Jr 2007-11-13 14:36:29 +00:00
parent 5e8be6978e
commit babfe78494
2 changed files with 43 additions and 3 deletions

View File

@ -155,14 +155,22 @@ class ModelChoiceField(ChoiceField):
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):
self.queryset = queryset
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)
self.queryset = queryset
def _get_queryset(self):
return self._queryset
def _set_queryset(self, queryset):
self._queryset = queryset
self.widget.choices = self.choices self.widget.choices = self.choices
queryset = property(_get_queryset, _set_queryset)
def _get_choices(self): def _get_choices(self):
# If self._choices is set, then somebody must have manually set # If self._choices is set, then somebody must have manually set
# the property self.choices. In this case, just return self._choices. # the property self.choices. In this case, just return self._choices.
@ -190,7 +198,7 @@ class ModelChoiceField(ChoiceField):
if value in ('', None): if value in ('', None):
return None return None
try: try:
value = self.queryset.model._default_manager.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(ugettext(u'Select a valid choice. That'
u' choice is not one of the' u' choice is not one of the'
@ -217,7 +225,7 @@ class ModelMultipleChoiceField(ModelChoiceField):
final_values = [] final_values = []
for val in value: for val in value:
try: try:
obj = self.queryset.model._default_manager.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(ugettext(u'Select a valid choice. %s is'
u' not one of the available' u' not one of the available'

View File

@ -440,6 +440,8 @@ the data in the database when the form is instantiated.
>>> from django.newforms import ModelChoiceField, ModelMultipleChoiceField >>> from django.newforms import ModelChoiceField, ModelMultipleChoiceField
>>> f = ModelChoiceField(Category.objects.all()) >>> f = ModelChoiceField(Category.objects.all())
>>> list(f.choices)
[(u'', u'---------'), (1, u'Entertainment'), (2, u"It's a test"), (3, u'Third'), (4, u'Fourth')]
>>> f.clean('') >>> f.clean('')
Traceback (most recent call last): Traceback (most recent call last):
... ...
@ -485,9 +487,23 @@ Traceback (most recent call last):
... ...
ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
# queryset can be changed after the field is created.
>>> f.queryset = Category.objects.exclude(name='Fourth')
>>> list(f.choices)
[(u'', u'---------'), (1, u'Entertainment'), (2, u"It's a test"), (3, u'Third')]
>>> f.clean(3)
<Category: Third>
>>> f.clean(4)
Traceback (most recent call last):
...
ValidationError: [u'Select a valid choice. That choice is not one of the available choices.']
# ModelMultipleChoiceField #################################################### # ModelMultipleChoiceField ####################################################
>>> f = ModelMultipleChoiceField(Category.objects.all()) >>> f = ModelMultipleChoiceField(Category.objects.all())
>>> list(f.choices)
[(1, u'Entertainment'), (2, u"It's a test"), (3, u'Third'), (4, u'Fourth')]
>>> f.clean(None) >>> f.clean(None)
Traceback (most recent call last): Traceback (most recent call last):
... ...
@ -552,6 +568,22 @@ Traceback (most recent call last):
... ...
ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] ValidationError: [u'Select a valid choice. 10 is not one of the available choices.']
# queryset can be changed after the field is created.
>>> f.queryset = Category.objects.exclude(name='Fourth')
>>> list(f.choices)
[(1, u'Entertainment'), (2, u"It's a test"), (3, u'Third')]
>>> f.clean([3])
[<Category: Third>]
>>> f.clean([4])
Traceback (most recent call last):
...
ValidationError: [u'Select a valid choice. 4 is not one of the available choices.']
>>> f.clean(['3', '4'])
Traceback (most recent call last):
...
ValidationError: [u'Select a valid choice. 4 is not one of the available choices.']
# PhoneNumberField ############################################################ # PhoneNumberField ############################################################
>>> PhoneNumberForm = form_for_model(PhoneNumber) >>> PhoneNumberForm = form_for_model(PhoneNumber)