mirror of
https://github.com/django/django.git
synced 2025-08-03 18:38:50 +00:00
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
This commit is contained in:
parent
5bec651a61
commit
ee96c7eb2d
2 changed files with 153 additions and 28 deletions
|
@ -289,6 +289,46 @@ existing Category instance.
|
|||
>>> Category.objects.get(id=3)
|
||||
<Category: Third>
|
||||
|
||||
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()
|
||||
<li>Headline: <input type="text" name="headline" maxlength="50" /></li>
|
||||
<li>Pub date: <input type="text" name="pub_date" /></li>
|
||||
<li>Writer: <select name="writer">
|
||||
<option value="" selected="selected">---------</option>
|
||||
<option value="1">Mike Royko</option>
|
||||
<option value="2">Bob Woodward</option>
|
||||
</select></li>
|
||||
<li>Article: <textarea name="article"></textarea></li>
|
||||
<li>Categories: <select multiple="multiple" name="categories">
|
||||
<option value="1">Entertainment</option>
|
||||
<option value="2">It's a test</option>
|
||||
<option value="3">Third</option>
|
||||
</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li>
|
||||
>>> Category.objects.create(name='Fourth', url='4th')
|
||||
<Category: Fourth>
|
||||
>>> Writer.objects.create(name='Carl Bernstein')
|
||||
<Writer: Carl Bernstein>
|
||||
>>> print f.as_ul()
|
||||
<li>Headline: <input type="text" name="headline" maxlength="50" /></li>
|
||||
<li>Pub date: <input type="text" name="pub_date" /></li>
|
||||
<li>Writer: <select name="writer">
|
||||
<option value="" selected="selected">---------</option>
|
||||
<option value="1">Mike Royko</option>
|
||||
<option value="2">Bob Woodward</option>
|
||||
<option value="3">Carl Bernstein</option>
|
||||
</select></li>
|
||||
<li>Article: <textarea name="article"></textarea></li>
|
||||
<li>Categories: <select multiple="multiple" name="categories">
|
||||
<option value="1">Entertainment</option>
|
||||
<option value="2">It's a test</option>
|
||||
<option value="3">Third</option>
|
||||
<option value="4">Fourth</option>
|
||||
</select> Hold down "Control", or "Command" on a Mac, to select more than one.</li>
|
||||
|
||||
# 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)
|
||||
<Category: It's a test>
|
||||
|
||||
# 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')
|
||||
<Category: Fifth>
|
||||
>>> f.clean(5)
|
||||
<Category: Fifth>
|
||||
|
||||
# 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')
|
||||
<Category: Entertainment>
|
||||
>>> 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.']
|
|||
[<Category: Entertainment>, <Category: It's a test>]
|
||||
>>> f.clean((1, '2'))
|
||||
[<Category: Entertainment>, <Category: It's a test>]
|
||||
>>> 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')
|
||||
<Category: Sixth>
|
||||
>>> f.clean([6])
|
||||
[<Category: Sixth>]
|
||||
|
||||
# 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.']
|
||||
"""}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue