From ee96c7eb2dea86e5bdaf93f7afa91b6f0128dd72 Mon Sep 17 00:00:00 2001 From: Adrian Holovaty Date: Wed, 21 Feb 2007 05:14:28 +0000 Subject: Fixed #3534 -- newforms ModelChoiceField and ModelMultipleChoiceField no longer cache choices. Instead, they calculate choices via a fresh database query each time the widget is rendered and clean() is called git-svn-id: http://code.djangoproject.com/svn/django/trunk@4552 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- tests/modeltests/model_forms/models.py | 93 ++++++++++++++++++++++++++++++---- 1 file changed, 84 insertions(+), 9 deletions(-) (limited to 'tests') diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index 63ec511838..38829ad662 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -289,6 +289,46 @@ existing Category instance. >>> Category.objects.get(id=3) +Here, we demonstrate that choices for a ForeignKey ChoiceField are determined +at runtime, based on the data in the database when the form is displayed, not +the data in the database when the form is instantiated. +>>> ArticleForm = form_for_model(Article) +>>> f = ArticleForm(auto_id=False) +>>> print f.as_ul() +
  • Headline:
  • +
  • Pub date:
  • +
  • Writer:
  • +
  • Article:
  • +
  • Categories: Hold down "Control", or "Command" on a Mac, to select more than one.
  • +>>> Category.objects.create(name='Fourth', url='4th') + +>>> Writer.objects.create(name='Carl Bernstein') + +>>> print f.as_ul() +
  • Headline:
  • +
  • Pub date:
  • +
  • Writer:
  • +
  • Article:
  • +
  • Categories: Hold down "Control", or "Command" on a Mac, to select more than one.
  • + # ModelChoiceField ############################################################ >>> from django.newforms import ModelChoiceField, ModelMultipleChoiceField @@ -311,13 +351,30 @@ ValidationError: [u'Select a valid choice. That choice is not one of the availab >>> f.clean(2) +# Add a Category object *after* the ModelChoiceField has already been +# instantiated. This proves clean() checks the database during clean() rather +# than caching it at time of instantiation. +>>> Category.objects.create(name='Fifth', url='5th') + +>>> f.clean(5) + + +# Delete a Category object *after* the ModelChoiceField has already been +# instantiated. This proves clean() checks the database during clean() rather +# than caching it at time of instantiation. +>>> Category.objects.get(url='5th').delete() +>>> f.clean(5) +Traceback (most recent call last): +... +ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] + >>> f = ModelChoiceField(Category.objects.filter(pk=1), required=False) >>> print f.clean('') None >>> f.clean('') >>> f.clean('1') ->>> f.clean('2') +>>> f.clean('100') Traceback (most recent call last): ... ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] @@ -345,29 +402,47 @@ ValidationError: [u'This field is required.'] [, ] >>> f.clean((1, '2')) [, ] ->>> f.clean(['nonexistent']) +>>> f.clean(['100']) Traceback (most recent call last): ... -ValidationError: [u'Select a valid choice. nonexistent is not one of the available choices.'] +ValidationError: [u'Select a valid choice. 100 is not one of the available choices.'] >>> f.clean('hello') Traceback (most recent call last): ... ValidationError: [u'Enter a list of values.'] + +# Add a Category object *after* the ModelChoiceField has already been +# instantiated. This proves clean() checks the database during clean() rather +# than caching it at time of instantiation. +>>> Category.objects.create(id=6, name='Sixth', url='6th') + +>>> f.clean([6]) +[] + +# Delete a Category object *after* the ModelChoiceField has already been +# instantiated. This proves clean() checks the database during clean() rather +# than caching it at time of instantiation. +>>> Category.objects.get(url='6th').delete() +>>> f.clean([6]) +Traceback (most recent call last): +... +ValidationError: [u'Select a valid choice. 6 is not one of the available choices.'] + >>> f = ModelMultipleChoiceField(Category.objects.all(), required=False) >>> f.clean([]) [] >>> f.clean(()) [] ->>> f.clean(['4']) +>>> f.clean(['10']) Traceback (most recent call last): ... -ValidationError: [u'Select a valid choice. 4 is not one of the available choices.'] ->>> f.clean(['3', '4']) +ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] +>>> f.clean(['3', '10']) Traceback (most recent call last): ... -ValidationError: [u'Select a valid choice. 4 is not one of the available choices.'] ->>> f.clean(['1', '5']) +ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] +>>> f.clean(['1', '10']) Traceback (most recent call last): ... -ValidationError: [u'Select a valid choice. 5 is not one of the available choices.'] +ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] """} -- cgit v1.3