diff options
| author | Adrian Holovaty <adrian@holovaty.com> | 2007-02-25 05:50:24 +0000 |
|---|---|---|
| committer | Adrian Holovaty <adrian@holovaty.com> | 2007-02-25 05:50:24 +0000 |
| commit | 8f1fb6da3a2eaae0e8c2351266900c1ae9d36403 (patch) | |
| tree | f26d97b57f425ac38fb54c69f8bf6171514c2903 /tests | |
| parent | 67e0248806e8adc03ddd81e9543f77b540ed1673 (diff) | |
newforms-admin: Merged to [4563]
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@4565 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/modeltests/model_forms/models.py | 180 | ||||
| -rw-r--r-- | tests/regressiontests/defaultfilters/tests.py | 48 | ||||
| -rw-r--r-- | tests/regressiontests/forms/tests.py | 94 |
3 files changed, 321 insertions, 1 deletions
diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index 657d506b33..e64174a23f 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -40,13 +40,27 @@ class Writer(models.Model): class Article(models.Model): headline = models.CharField(maxlength=50) pub_date = models.DateField() + created = models.DateField(editable=False) writer = models.ForeignKey(Writer) article = models.TextField() categories = models.ManyToManyField(Category, blank=True) + def save(self): + import datetime + if not self.id: + self.created = datetime.date.today() + return super(Article, self).save() + def __str__(self): return self.headline +class PhoneNumber(models.Model): + phone = models.PhoneNumberField() + description = models.CharField(maxlength=20) + + def __str__(self): + return self.phone + __test__ = {'API_TESTS': """ >>> from django.newforms import form_for_model, form_for_instance, save_instance, BaseForm, Form, CharField >>> import datetime @@ -281,4 +295,170 @@ existing Category instance. <Category: Third> >>> 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 + +>>> f = ModelChoiceField(Category.objects.all()) +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean(0) +Traceback (most recent call last): +... +ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] +>>> f.clean(3) +<Category: Third> +>>> 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('100') +Traceback (most recent call last): +... +ValidationError: [u'Select a valid choice. That choice is not one of the available choices.'] + +# ModelMultipleChoiceField #################################################### + +>>> f = ModelMultipleChoiceField(Category.objects.all()) +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean([]) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean([1]) +[<Category: Entertainment>] +>>> f.clean([2]) +[<Category: It's a test>] +>>> f.clean(['1']) +[<Category: Entertainment>] +>>> f.clean(['1', '2']) +[<Category: Entertainment>, <Category: It's a test>] +>>> f.clean([1, '2']) +[<Category: Entertainment>, <Category: It's a test>] +>>> f.clean((1, '2')) +[<Category: Entertainment>, <Category: It's a test>] +>>> f.clean(['100']) +Traceback (most recent call last): +... +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(['10']) +Traceback (most recent call last): +... +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. 10 is not one of the available choices.'] +>>> f.clean(['1', '10']) +Traceback (most recent call last): +... +ValidationError: [u'Select a valid choice. 10 is not one of the available choices.'] + +# PhoneNumberField ############################################################ + +>>> PhoneNumberForm = form_for_model(PhoneNumber) +>>> f = PhoneNumberForm({'phone': '(312) 555-1212', 'description': 'Assistance'}) +>>> f.is_valid() +True +>>> f.clean_data +{'phone': u'312-555-1212', 'description': u'Assistance'} """} diff --git a/tests/regressiontests/defaultfilters/tests.py b/tests/regressiontests/defaultfilters/tests.py index b4ec9a0b03..c850806052 100644 --- a/tests/regressiontests/defaultfilters/tests.py +++ b/tests/regressiontests/defaultfilters/tests.py @@ -388,7 +388,53 @@ False >>> phone2numeric('0800 flowers') '0800 3569377' - +# Filters shouldn't break if passed non-strings +>>> addslashes(123) +'123' +>>> linenumbers(123) +'1. 123' +>>> lower(123) +'123' +>>> make_list(123) +['1', '2', '3'] +>>> slugify(123) +'123' +>>> title(123) +'123' +>>> truncatewords(123, 2) +'123' +>>> upper(123) +'123' +>>> urlencode(123) +'123' +>>> urlize(123) +'123' +>>> urlizetrunc(123, 1) +'123' +>>> wordcount(123) +1 +>>> wordwrap(123, 2) +'123' +>>> ljust('123', 4) +'123 ' +>>> rjust('123', 4) +' 123' +>>> center('123', 5) +' 123 ' +>>> center('123', 6) +' 123 ' +>>> cut(123, '2') +'13' +>>> escape(123) +'123' +>>> linebreaks(123) +'<p>123</p>' +>>> linebreaksbr(123) +'123' +>>> removetags(123, 'a') +'123' +>>> striptags(123) +'123' """ diff --git a/tests/regressiontests/forms/tests.py b/tests/regressiontests/forms/tests.py index c4502b2202..db3969429e 100644 --- a/tests/regressiontests/forms/tests.py +++ b/tests/regressiontests/forms/tests.py @@ -318,6 +318,7 @@ The value is compared to its str(): </select> The 'choices' argument can be any iterable: +>>> from itertools import chain >>> def get_choices(): ... for i in range(5): ... yield (i, i) @@ -329,6 +330,17 @@ The 'choices' argument can be any iterable: <option value="3">3</option> <option value="4">4</option> </select> +>>> things = ({'id': 1, 'name': 'And Boom'}, {'id': 2, 'name': 'One More Thing!'}) +>>> class SomeForm(Form): +... somechoice = ChoiceField(choices=chain((('', '-'*9),), [(thing['id'], thing['name']) for thing in things])) +>>> f = SomeForm() +>>> f.as_table() +u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>' +>>> f.as_table() +u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="" selected="selected">---------</option>\n<option value="1">And Boom</option>\n<option value="2">One More Thing!</option>\n</select></td></tr>' +>>> f = SomeForm({'somechoice': 2}) +>>> f.as_table() +u'<tr><th><label for="id_somechoice">Somechoice:</label></th><td><select name="somechoice" id="id_somechoice">\n<option value="">---------</option>\n<option value="1">And Boom</option>\n<option value="2" selected="selected">One More Thing!</option>\n</select></td></tr>' You can also pass 'choices' to the constructor: >>> w = Select(choices=[(1, 1), (2, 2), (3, 3)]) @@ -1999,6 +2011,19 @@ For a form with a <select>, use ChoiceField: <option value="J">Java</option> </select> +A subtlety: If one of the choices' value is the empty string and the form is +unbound, then the <option> for the empty-string choice will get selected="selected". +>>> class FrameworkForm(Form): +... name = CharField() +... language = ChoiceField(choices=[('', '------'), ('P', 'Python'), ('J', 'Java')]) +>>> f = FrameworkForm(auto_id=False) +>>> print f['language'] +<select name="language"> +<option value="" selected="selected">------</option> +<option value="P">Python</option> +<option value="J">Java</option> +</select> + You can specify widget attributes in the Widget constructor. >>> class FrameworkForm(Form): ... name = CharField() @@ -3304,6 +3329,75 @@ u'' >>> f.clean('') u'' +# USPhoneNumberField ########################################################## + +USPhoneNumberField validates that the data is a valid U.S. phone number, +including the area code. It's normalized to XXX-XXX-XXXX format. +>>> from django.contrib.localflavor.usa.forms import USPhoneNumberField +>>> f = USPhoneNumberField() +>>> f.clean('312-555-1212') +u'312-555-1212' +>>> f.clean('3125551212') +u'312-555-1212' +>>> f.clean('312 555-1212') +u'312-555-1212' +>>> f.clean('(312) 555-1212') +u'312-555-1212' +>>> f.clean('312 555 1212') +u'312-555-1212' +>>> f.clean('312.555.1212') +u'312-555-1212' +>>> f.clean('312.555-1212') +u'312-555-1212' +>>> f.clean(' (312) 555.1212 ') +u'312-555-1212' +>>> f.clean('555-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean('312-55-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean(None) +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] +>>> f.clean('') +Traceback (most recent call last): +... +ValidationError: [u'This field is required.'] + +>>> f = USPhoneNumberField(required=False) +>>> f.clean('312-555-1212') +u'312-555-1212' +>>> f.clean('3125551212') +u'312-555-1212' +>>> f.clean('312 555-1212') +u'312-555-1212' +>>> f.clean('(312) 555-1212') +u'312-555-1212' +>>> f.clean('312 555 1212') +u'312-555-1212' +>>> f.clean('312.555.1212') +u'312-555-1212' +>>> f.clean('312.555-1212') +u'312-555-1212' +>>> f.clean(' (312) 555.1212 ') +u'312-555-1212' +>>> f.clean('555-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean('312-55-1212') +Traceback (most recent call last): +... +ValidationError: [u'Phone numbers must be in XXX-XXX-XXXX format.'] +>>> f.clean(None) +u'' +>>> f.clean('') +u'' + # USStateField ################################################################ USStateField validates that the data is either an abbreviation or name of a |
