1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +00:00

unicode: Merged with trunk up to [4970].

git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@4973 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2007-04-09 11:09:17 +00:00
parent e5adc5a427
commit 349bf5a355
21 changed files with 326 additions and 121 deletions

View File

@ -88,6 +88,7 @@ answer newbie questions, and generally made Django that much better:
Dirk Eschler <dirk.eschler@gmx.net> Dirk Eschler <dirk.eschler@gmx.net>
Marc Fargas <telenieko@telenieko.com> Marc Fargas <telenieko@telenieko.com>
favo@exoweb.net favo@exoweb.net
Matthew Flanagan <http://wadofstuff.blogspot.com>
Eric Floehr <eric@intellovations.com> Eric Floehr <eric@intellovations.com>
Jorge Gajon <gajon@gajon.org> Jorge Gajon <gajon@gajon.org>
gandalf@owca.info gandalf@owca.info

View File

@ -0,0 +1,17 @@
"""
An alphabetical list of states for use as `choices` in a formfield.
This exists in this standalone file so that it's only imported into memory
when explicitly needed.
"""
STATE_CHOICES = (
('ACT', 'Australian Capital Territory'),
('NSW', 'New South Wales'),
('NT', 'Northern Territory'),
('QLD', 'Queensland'),
('SA', 'South Australia'),
('TAS', 'Tasmania'),
('VIC', 'Victoria'),
('WA', 'Western Australia'),
)

View File

@ -0,0 +1,43 @@
"""
Australian-specific Form helpers
"""
from django.newforms import ValidationError
from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
from django.newforms.util import smart_unicode
from django.utils.translation import gettext
import re
PHONE_DIGITS_RE = re.compile(r'^(\d{10})$')
class AUPostCodeField(RegexField):
"""Australian post code field."""
def __init__(self, *args, **kwargs):
super(AUPostCodeField, self).__init__(r'^\d{4}$',
max_length=None, min_length=None,
error_message=gettext(u'Enter a 4 digit post code.'),
*args, **kwargs)
class AUPhoneNumberField(Field):
"""Australian phone number field."""
def clean(self, value):
"""Validate a phone number. Strips parentheses, whitespace and
hyphens.
"""
super(AUPhoneNumberField, self).clean(value)
if value in EMPTY_VALUES:
return u''
value = re.sub('(\(|\)|\s+|-)', '', smart_unicode(value))
phone_match = PHONE_DIGITS_RE.search(value)
if phone_match:
return u'%s' % phone_match.group(1)
raise ValidationError(u'Phone numbers must contain 10 digits.')
class AUStateSelect(Select):
"""
A Select widget that uses a list of Australian states/territories as its
choices.
"""
def __init__(self, attrs=None):
from au_states import STATE_CHOICES # relative import
super(AUStateSelect, self).__init__(attrs, choices=STATE_CHOICES)

View File

@ -1,11 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
A brazilian mapping of state misspellings/abbreviations to normalized An alphabetical list of Brazilian states for use as `choices` in a formfield.
abbreviations, and an alphabetical list of states for use as `choices
in a formfield.
This exists in this standalone file so that it's only imported into This exists in this standalone file so that it's only imported into memory
memory when explicitly needed. when explicitly needed.
""" """
STATE_CHOICES = ( STATE_CHOICES = (

View File

@ -26,7 +26,7 @@ class FISocialSecurityNumber(Field):
def clean(self, value): def clean(self, value):
super(FISocialSecurityNumber, self).clean(value) super(FISocialSecurityNumber, self).clean(value)
if value in EMPTY_VALUES: if value in EMPTY_VALUES:
return u'' return u''
checkmarks = "0123456789ABCDEFHJKLMNPRSTUVWXY" checkmarks = "0123456789ABCDEFHJKLMNPRSTUVWXY"
result = re.match(r"""^ result = re.match(r"""^
@ -35,13 +35,11 @@ class FISocialSecurityNumber(Field):
(\d{2})) (\d{2}))
[A+-] [A+-]
(?P<serial>(\d{3})) (?P<serial>(\d{3}))
(?P<chechsum>[%s])$""" % checkmarks, value, re.VERBOSE | re.IGNORECASE) (?P<checksum>[%s])$""" % checkmarks, value, re.VERBOSE | re.IGNORECASE)
if not result: if not result:
raise ValidationError(gettext(u'Enter a valid Finnish social security number.')) raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))
checksum = int(result.groupdict()['date'] + result.groupdict()['serial']) gd = result.groupdict()
checksum = int(gd['date'] + gd['serial'])
if checkmarks[checksum % len(checkmarks)] == result.groupdict()['chechsum'].upper(): if checkmarks[checksum % len(checkmarks)] == gd['checksum'].upper():
return u'%s' % value.upper() return u'%s' % value.upper()
raise ValidationError(gettext(u'Enter a valid Finnish social security number.')) raise ValidationError(gettext(u'Enter a valid Finnish social security number.'))

View File

@ -761,7 +761,7 @@ class PhoneNumberField(IntegerField):
validators.isValidPhone(field_data, all_data) validators.isValidPhone(field_data, all_data)
def formfield(self, **kwargs): def formfield(self, **kwargs):
from django.contrib.localflavor.usa.forms import USPhoneNumberField from django.contrib.localflavor.us.forms import USPhoneNumberField
defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text} defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name), 'help_text': self.help_text}
defaults.update(kwargs) defaults.update(kwargs)
return USPhoneNumberField(**defaults) return USPhoneNumberField(**defaults)

View File

@ -121,6 +121,12 @@ class FileInput(Input):
input_type = 'file' input_type = 'file'
class Textarea(Widget): class Textarea(Widget):
def __init__(self, attrs=None):
# The 'rows' and 'cols' attributes are required for HTML correctness.
self.attrs = {'cols': '40', 'rows': '10'}
if attrs:
self.attrs.update(attrs)
def render(self, name, value, attrs=None): def render(self, name, value, attrs=None):
if value is None: value = '' if value is None: value = ''
value = smart_unicode(value) value = smart_unicode(value)

View File

@ -144,6 +144,7 @@ def technical_404_response(request, exception):
t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template') t = Template(TECHNICAL_404_TEMPLATE, name='Technical 404 template')
c = Context({ c = Context({
'root_urlconf': settings.ROOT_URLCONF, 'root_urlconf': settings.ROOT_URLCONF,
'request_path': request.path[1:], # Trim leading slash
'urlpatterns': tried, 'urlpatterns': tried,
'reason': str(exception), 'reason': str(exception),
'request': request, 'request': request,
@ -591,7 +592,7 @@ TECHNICAL_404_TEMPLATE = """
<li>{{ pattern|escape }}</li> <li>{{ pattern|escape }}</li>
{% endfor %} {% endfor %}
</ol> </ol>
<p>The current URL, <code>{{ request.path|escape }}</code>, didn't match any of these.</p> <p>The current URL, <code>{{ request_path|escape }}</code>, didn't match any of these.</p>
{% else %} {% else %}
<p>{{ reason|escape }}</p> <p>{{ reason|escape }}</p>
{% endif %} {% endif %}

View File

@ -29,6 +29,9 @@ Generally, when working on a single Django project, it's easier to use
``--settings`` command line option, if you need to switch between multiple ``--settings`` command line option, if you need to switch between multiple
Django settings files. Django settings files.
The command-line examples throughout this document use ``django-admin.py`` to
be consistent, but any example can use ``manage.py`` just as well.
Usage Usage
===== =====
@ -512,7 +515,8 @@ and `2` is verbose output.
------------ ------------
Example usage:: Example usage::
django-admin.py manage.py --adminmedia=/tmp/new-admin-style/
django-admin.py --adminmedia=/tmp/new-admin-style/
Tells Django where to find the various CSS and JavaScript files for the admin Tells Django where to find the various CSS and JavaScript files for the admin
interface when running the development server. Normally these files are served interface when running the development server. Normally these files are served

View File

@ -42,25 +42,25 @@ On the Web
The most recent version of the Django documentation lives at The most recent version of the Django documentation lives at
http://www.djangoproject.com/documentation/ . These HTML pages are generated http://www.djangoproject.com/documentation/ . These HTML pages are generated
automatically from the text files in source control every 15 minutes. That automatically from the text files in source control. That means they reflect
means they reflect the "latest and greatest" in Django -- they include the very the "latest and greatest" in Django -- they include the very latest
latest corrections and additions, and they discuss the latest Django features, corrections and additions, and they discuss the latest Django features,
which may only be available to users of the Django development version. (See which may only be available to users of the Django development version. (See
"Differences between versions" below.) "Differences between versions" below.)
A key advantage of the Web-based documentation is the comment section at the We encourage you to help improve the docs by submitting changes, corrections
bottom of each document. This is an area for anybody to submit changes, and suggestions in the `ticket system`_. The Django developers actively monitor
corrections and suggestions about the given document. The Django developers the ticket system and use your feedback to improve the documentation for
frequently monitor the comments there and use them to improve the documentation everybody.
for everybody.
We encourage you to help improve the docs: it's easy! Note, however, that Note, however, that tickets should explicitly relate to the documentation,
comments should explicitly relate to the documentation, rather than asking rather than asking broad tech-support questions. If you need help with your
broad tech-support questions. If you need help with your particular Django particular Django setup, try the `django-users mailing list`_ or the
setup, try the `django-users mailing list`_ instead of posting a comment to the `#django IRC channel`_ instead.
documentation.
.. _ticket system: http://code.djangoproject.com/simpleticket?component=Documentation
.. _django-users mailing list: http://groups.google.com/group/django-users .. _django-users mailing list: http://groups.google.com/group/django-users
.. _#django IRC channel: irc://irc.freenode.net/django
In plain text In plain text
------------- -------------
@ -134,14 +134,6 @@ We follow this policy:
frozen document that says "These docs are frozen for Django version XXX" frozen document that says "These docs are frozen for Django version XXX"
and links to the current version of that document. and links to the current version of that document.
* Once a document is frozen for a Django release, we remove comments from
that page, in favor of having comments on the latest version of that
document. This is for the sake of maintainability and usability, so that
users have one, and only one, place to leave comments on a particular
document. We realize that some people may be stuck on a previous version
of Django, but we believe the usability problems with multiple versions
of a document the outweigh the benefits.
* The `main documentation Web page`_ includes links to documentation for * The `main documentation Web page`_ includes links to documentation for
all previous versions. all previous versions.

View File

@ -39,11 +39,11 @@ Auto-generate the models
Django comes with a utility that can create models by introspecting an existing Django comes with a utility that can create models by introspecting an existing
database. You can view the output by running this command:: database. You can view the output by running this command::
django-admin.py inspectdb --settings=path.to.settings python manage.py inspectdb
Save this as a file by using standard Unix output redirection:: Save this as a file by using standard Unix output redirection::
django-admin.py inspectdb --settings=path.to.settings > models.py python manage.py inspectdb > models.py
This feature is meant as a shortcut, not as definitive model generation. See This feature is meant as a shortcut, not as definitive model generation. See
the `django-admin.py documentation`_ for more information. the `django-admin.py documentation`_ for more information.
@ -60,7 +60,7 @@ Install the core Django tables
Next, run the ``manage.py syncdb`` command to install any extra needed database Next, run the ``manage.py syncdb`` command to install any extra needed database
records such as admin permissions and content types:: records such as admin permissions and content types::
django-admin.py init --settings=path.to.settings python manage.py syncdb
See whether it worked See whether it worked
===================== =====================

View File

@ -57,17 +57,16 @@ on it, you'll need to tell mod_python::
.. caution:: .. caution::
Is you are using Windows, remember that the path will contain backslashes. If you're using Windows, remember that the path will contain backslashes.
This string is passed through Python's string parser twice, so you need to This string is passed through Python's string parser twice, so you need to
escape each backslash **twice**:: escape each backslash **twice**::
PythonPath "['c:\\\\path\\\\to\\\\project'] + sys.path" PythonPath "['c:\\\\path\\\\to\\\\project'] + sys.path"
or use raw strings:: Or, use raw strings::
PythonPath "[r'c:\\path\\to\\project'] + sys.path" PythonPath "[r'c:\\path\\to\\project'] + sys.path"
You can also add directives such as ``PythonAutoReload Off`` for performance. You can also add directives such as ``PythonAutoReload Off`` for performance.
See the `mod_python documentation`_ for a full list of options. See the `mod_python documentation`_ for a full list of options.
@ -161,7 +160,7 @@ If, however, you have no option but to serve media files on the same Apache
``VirtualHost`` as Django, here's how you can turn off mod_python for a ``VirtualHost`` as Django, here's how you can turn off mod_python for a
particular part of the site:: particular part of the site::
<Location "/media/"> <Location "/media">
SetHandler None SetHandler None
</Location> </Location>
@ -178,7 +177,7 @@ the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
SetEnv DJANGO_SETTINGS_MODULE mysite.settings SetEnv DJANGO_SETTINGS_MODULE mysite.settings
</Location> </Location>
<Location "media"> <Location "/media">
SetHandler None SetHandler None
</Location> </Location>

View File

@ -483,8 +483,8 @@ In order to use the ``Http404`` exception to its fullest, you should create a
template that is displayed when a 404 error is raised. This template should be template that is displayed when a 404 error is raised. This template should be
called ``404.html`` and located in the top level of your template tree. called ``404.html`` and located in the top level of your template tree.
Customing error views Customizing error views
--------------------- -----------------------
The 404 (page not found) view The 404 (page not found) view
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -192,10 +192,11 @@ The remaining arguments should be tuples in this format::
url url
--- ---
**New in development version**
The ``url()`` function can be used instead of a tuple as an argument to **New in Django development version**
``patterns()``. This is convenient if you wish to specify a name without the
You can use the ``url()`` function, instead of a tuple, as an argument to
``patterns()``. This is convenient if you want to specify a name without the
optional extra arguments dictionary. For example:: optional extra arguments dictionary. For example::
urlpatterns = patterns('', urlpatterns = patterns('',
@ -498,26 +499,40 @@ the view prefix (as explained in "The view prefix" above) will have no effect.
Naming URL patterns Naming URL patterns
=================== ===================
**New in development version** **New in Django development version**
It is fairly common to use the same view function in multiple URL patterns in It's fairly common to use the same view function in multiple URL patterns in
your URLConf. This leads to problems when you come to do reverse URL matching, your URLconf. For example, these two URL patterns both point to the ``archive``
because the ``permalink()`` decorator and ``{% url %}`` template tag use the view::
name of the view function to find a match.
To solve this problem, you can give a name to each of your URL patterns in urlpatterns = patterns('',
order to distinguish them from other patterns using the same views and (r'/archive/(\d{4})/$', archive),
parameters. You can then use this name wherever you would otherwise use the (r'/archive-summary/(\d{4})/$', archive, {'summary': True}),
name of the view function. For example, if you URLConf contains:: )
This is completely valid, but it leads to problems when you try to do reverse
URL matching (through the ``permalink()`` decorator or the ``{% url %}``
template tag). Continuing this example, if you wanted to retrieve the URL for
the ``archive`` view, Django's reverse URL matcher would get confused, because
*two* URLpatterns point at that view.
To solve this problem, Django supports **named URL patterns**. That is, you can
give a name to a URL pattern in order to distinguish it from other patterns
using the same view and parameters. Then, you can use this name in reverse URL
matching.
Here's the above example, rewritten to used named URL patterns::
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'/archive/(\d{4})/$', archive, name="full-archive"), url(r'/archive/(\d{4})/$', archive, name="full-archive"),
url(r'/archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"), url(r'/archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
) )
...you could refer to either the summary archive view in a template as:: With these names in place (``full-archive`` and ``arch-summary``), you can
target each pattern individually by using its name::
{% url arch-summary 1945 %} {% url arch-summary 1945 %}
{% url full-archive 2007 %}
Even though both URL patterns refer to the ``archive`` view here, using the Even though both URL patterns refer to the ``archive`` view here, using the
``name`` parameter to ``url()`` allows you to tell them apart in templates. ``name`` parameter to ``url()`` allows you to tell them apart in templates.
@ -527,11 +542,12 @@ not restricted to valid Python names.
.. note:: .. note::
Make sure that when you name your URLs, you use names that are unlikely to When you name your URL patterns, make sure you use names that are unlikely
clash with any other application's choice of names. If you call your URL to clash with any other application's choice of names. If you call your URL
pattern *comment* and another application does the same thing, there is no pattern ``comment``, and another application does the same thing, there's
guarantee which URL will be inserted into your template when you use this no guarantee which URL will be inserted into your template when you use
name. Putting a prefix on your URL names, perhaps derived from this name.
the application name, will decrease the chances of collision. Something
like *myapp-comment* is recommended over simply *comment*.
Putting a prefix on your URL names, perhaps derived from the application
name, will decrease the chances of collision. We recommend something like
``myapp-comment`` instead of ``comment``.

View File

@ -159,7 +159,7 @@ represented by a ChoiceField.
<option value="1">Mike Royko</option> <option value="1">Mike Royko</option>
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
</select></td></tr> </select></td></tr>
<tr><th>Article:</th><td><textarea name="article"></textarea></td></tr> <tr><th>Article:</th><td><textarea rows="10" cols="40" name="article"></textarea></td></tr>
<tr><th>Categories:</th><td><select multiple="multiple" name="categories"> <tr><th>Categories:</th><td><select multiple="multiple" name="categories">
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
@ -199,7 +199,7 @@ current values are inserted as 'initial' data in each Field.
<option value="1" selected="selected">Mike Royko</option> <option value="1" selected="selected">Mike Royko</option>
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
</select></li> </select></li>
<li>Article: <textarea name="article">Hello.</textarea></li> <li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li>
<li>Categories: <select multiple="multiple" name="categories"> <li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
@ -231,7 +231,7 @@ Add some categories and test the many-to-many form output.
<option value="1" selected="selected">Mike Royko</option> <option value="1" selected="selected">Mike Royko</option>
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
</select></li> </select></li>
<li>Article: <textarea name="article">Hello.</textarea></li> <li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li>
<li>Categories: <select multiple="multiple" name="categories"> <li>Categories: <select multiple="multiple" name="categories">
<option value="1" selected="selected">Entertainment</option> <option value="1" selected="selected">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
@ -309,7 +309,7 @@ the data in the database when the form is instantiated.
<option value="1">Mike Royko</option> <option value="1">Mike Royko</option>
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
</select></li> </select></li>
<li>Article: <textarea name="article"></textarea></li> <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li>
<li>Categories: <select multiple="multiple" name="categories"> <li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>
@ -328,7 +328,7 @@ the data in the database when the form is instantiated.
<option value="2">Bob Woodward</option> <option value="2">Bob Woodward</option>
<option value="3">Carl Bernstein</option> <option value="3">Carl Bernstein</option>
</select></li> </select></li>
<li>Article: <textarea name="article"></textarea></li> <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li>
<li>Categories: <select multiple="multiple" name="categories"> <li>Categories: <select multiple="multiple" name="categories">
<option value="1">Entertainment</option> <option value="1">Entertainment</option>
<option value="2">It&#39;s a test</option> <option value="2">It&#39;s a test</option>

View File

@ -6,7 +6,7 @@ localflavor_tests = r"""
USZipCodeField validates that the data is either a five-digit U.S. zip code or USZipCodeField validates that the data is either a five-digit U.S. zip code or
a zip+4. a zip+4.
>>> from django.contrib.localflavor.usa.forms import USZipCodeField >>> from django.contrib.localflavor.us.forms import USZipCodeField
>>> f = USZipCodeField() >>> f = USZipCodeField()
>>> f.clean('60606') >>> f.clean('60606')
u'60606' u'60606'
@ -67,7 +67,7 @@ u''
USPhoneNumberField validates that the data is a valid U.S. phone number, USPhoneNumberField validates that the data is a valid U.S. phone number,
including the area code. It's normalized to XXX-XXX-XXXX format. including the area code. It's normalized to XXX-XXX-XXXX format.
>>> from django.contrib.localflavor.usa.forms import USPhoneNumberField >>> from django.contrib.localflavor.us.forms import USPhoneNumberField
>>> f = USPhoneNumberField() >>> f = USPhoneNumberField()
>>> f.clean('312-555-1212') >>> f.clean('312-555-1212')
u'312-555-1212' u'312-555-1212'
@ -136,7 +136,7 @@ u''
USStateField validates that the data is either an abbreviation or name of a USStateField validates that the data is either an abbreviation or name of a
U.S. state. U.S. state.
>>> from django.contrib.localflavor.usa.forms import USStateField >>> from django.contrib.localflavor.us.forms import USStateField
>>> f = USStateField() >>> f = USStateField()
>>> f.clean('il') >>> f.clean('il')
u'IL' u'IL'
@ -181,7 +181,7 @@ u''
USStateSelect is a Select widget that uses a list of U.S. states/territories USStateSelect is a Select widget that uses a list of U.S. states/territories
as its choices. as its choices.
>>> from django.contrib.localflavor.usa.forms import USStateSelect >>> from django.contrib.localflavor.us.forms import USStateSelect
>>> w = USStateSelect() >>> w = USStateSelect()
>>> print w.render('state', 'IL') >>> print w.render('state', 'IL')
<select name="state"> <select name="state">
@ -247,7 +247,7 @@ as its choices.
</select> </select>
# USSocialSecurityNumberField ################################################# # USSocialSecurityNumberField #################################################
>>> from django.contrib.localflavor.usa.forms import USSocialSecurityNumberField >>> from django.contrib.localflavor.us.forms import USSocialSecurityNumberField
>>> f = USSocialSecurityNumberField() >>> f = USSocialSecurityNumberField()
>>> f.clean('987-65-4330') >>> f.clean('987-65-4330')
u'987-65-4330' u'987-65-4330'
@ -882,4 +882,134 @@ u'9786324830D-6104243-0910271-2'
Traceback (most recent call last): Traceback (most recent call last):
... ...
ValidationError: [u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.'] ValidationError: [u'Enter a valid German identity card number in XXXXXXXXXXX-XXXXXXX-XXXXXXX-X format.']
## AUPostCodeField ##########################################################
A field that accepts a four digit Australian post code.
>>> from django.contrib.localflavor.au.forms import AUPostCodeField
>>> f = AUPostCodeField()
>>> f.clean('1234')
u'1234'
>>> f.clean('2000')
u'2000'
>>> f.clean('abcd')
Traceback (most recent call last):
...
ValidationError: [u'Enter a 4 digit post code.']
>>> f.clean('20001')
Traceback (most recent call last):
...
ValidationError: [u'Enter a 4 digit post code.']
>>> 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 = AUPostCodeField(required=False)
>>> f.clean('1234')
u'1234'
>>> f.clean('2000')
u'2000'
>>> f.clean('abcd')
Traceback (most recent call last):
...
ValidationError: [u'Enter a 4 digit post code.']
>>> f.clean('20001')
Traceback (most recent call last):
...
ValidationError: [u'Enter a 4 digit post code.']
>>> f.clean(None)
u''
>>> f.clean('')
u''
## AUPhoneNumberField ########################################################
A field that accepts a 10 digit Australian phone number.
llows spaces and parentheses around area code.
>>> from django.contrib.localflavor.au.forms import AUPhoneNumberField
>>> f = AUPhoneNumberField()
>>> f.clean('1234567890')
u'1234567890'
>>> f.clean('0213456789')
u'0213456789'
>>> f.clean('02 13 45 67 89')
u'0213456789'
>>> f.clean('(02) 1345 6789')
u'0213456789'
>>> f.clean('(02) 1345-6789')
u'0213456789'
>>> f.clean('(02)1345-6789')
u'0213456789'
>>> f.clean('0408 123 456')
u'0408123456'
>>> f.clean('123')
Traceback (most recent call last):
...
ValidationError: [u'Phone numbers must contain 10 digits.']
>>> f.clean('1800DJANGO')
Traceback (most recent call last):
...
ValidationError: [u'Phone numbers must contain 10 digits.']
>>> 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 = AUPhoneNumberField(required=False)
>>> f.clean('1234567890')
u'1234567890'
>>> f.clean('0213456789')
u'0213456789'
>>> f.clean('02 13 45 67 89')
u'0213456789'
>>> f.clean('(02) 1345 6789')
u'0213456789'
>>> f.clean('(02) 1345-6789')
u'0213456789'
>>> f.clean('(02)1345-6789')
u'0213456789'
>>> f.clean('0408 123 456')
u'0408123456'
>>> f.clean('123')
Traceback (most recent call last):
...
ValidationError: [u'Phone numbers must contain 10 digits.']
>>> f.clean('1800DJANGO')
Traceback (most recent call last):
...
ValidationError: [u'Phone numbers must contain 10 digits.']
>>> f.clean(None)
u''
>>> f.clean('')
u''
## AUStateSelect #############################################################
AUStateSelect is a Select widget that uses a list of Australian
states/territories as its choices.
>>> from django.contrib.localflavor.au.forms import AUStateSelect
>>> f = AUStateSelect()
>>> print f.render('state', 'NSW')
<select name="state">
<option value="ACT">Australian Capital Territory</option>
<option value="NSW" selected="selected">New South Wales</option>
<option value="NT">Northern Territory</option>
<option value="QLD">Queensland</option>
<option value="SA">South Australia</option>
<option value="TAS">Tasmania</option>
<option value="VIC">Victoria</option>
<option value="WA">Western Australia</option>
</select>
""" """

View File

@ -193,30 +193,30 @@ u'<input type="file" class="fun" value="\u0160\u0110\u0106\u017d\u0107\u017e\u01
>>> w = Textarea() >>> w = Textarea()
>>> w.render('msg', '') >>> w.render('msg', '')
u'<textarea name="msg"></textarea>' u'<textarea rows="10" cols="40" name="msg"></textarea>'
>>> w.render('msg', None) >>> w.render('msg', None)
u'<textarea name="msg"></textarea>' u'<textarea rows="10" cols="40" name="msg"></textarea>'
>>> w.render('msg', 'value') >>> w.render('msg', 'value')
u'<textarea name="msg">value</textarea>' u'<textarea rows="10" cols="40" name="msg">value</textarea>'
>>> w.render('msg', 'some "quoted" & ampersanded value') >>> w.render('msg', 'some "quoted" & ampersanded value')
u'<textarea name="msg">some &quot;quoted&quot; &amp; ampersanded value</textarea>' u'<textarea rows="10" cols="40" name="msg">some &quot;quoted&quot; &amp; ampersanded value</textarea>'
>>> w.render('msg', 'value', attrs={'class': 'pretty'}) >>> w.render('msg', 'value', attrs={'class': 'pretty', 'rows': 20})
u'<textarea name="msg" class="pretty">value</textarea>' u'<textarea class="pretty" rows="20" cols="40" name="msg">value</textarea>'
You can also pass 'attrs' to the constructor: You can also pass 'attrs' to the constructor:
>>> w = Textarea(attrs={'class': 'pretty'}) >>> w = Textarea(attrs={'class': 'pretty'})
>>> w.render('msg', '') >>> w.render('msg', '')
u'<textarea class="pretty" name="msg"></textarea>' u'<textarea rows="10" cols="40" name="msg" class="pretty"></textarea>'
>>> w.render('msg', 'example') >>> w.render('msg', 'example')
u'<textarea class="pretty" name="msg">example</textarea>' u'<textarea rows="10" cols="40" name="msg" class="pretty">example</textarea>'
'attrs' passed to render() get precedence over those passed to the constructor: 'attrs' passed to render() get precedence over those passed to the constructor:
>>> w = Textarea(attrs={'class': 'pretty'}) >>> w = Textarea(attrs={'class': 'pretty'})
>>> w.render('msg', '', attrs={'class': 'special'}) >>> w.render('msg', '', attrs={'class': 'special'})
u'<textarea class="special" name="msg"></textarea>' u'<textarea rows="10" cols="40" name="msg" class="special"></textarea>'
>>> w.render('msg', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'}) >>> w.render('msg', 'ŠĐĆŽćžšđ', attrs={'class': 'fun'})
u'<textarea class="fun" name="msg">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</textarea>' u'<textarea rows="10" cols="40" name="msg" class="fun">\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111</textarea>'
# CheckboxInput Widget ######################################################## # CheckboxInput Widget ########################################################
@ -1966,12 +1966,12 @@ Any Field can have a Widget class passed to its constructor:
>>> print f['subject'] >>> print f['subject']
<input type="text" name="subject" /> <input type="text" name="subject" />
>>> print f['message'] >>> print f['message']
<textarea name="message"></textarea> <textarea rows="10" cols="40" name="message"></textarea>
as_textarea(), as_text() and as_hidden() are shortcuts for changing the output as_textarea(), as_text() and as_hidden() are shortcuts for changing the output
widget type: widget type:
>>> f['subject'].as_textarea() >>> f['subject'].as_textarea()
u'<textarea name="subject"></textarea>' u'<textarea rows="10" cols="40" name="subject"></textarea>'
>>> f['message'].as_text() >>> f['message'].as_text()
u'<input type="text" name="message" />' u'<input type="text" name="message" />'
>>> f['message'].as_hidden() >>> f['message'].as_hidden()
@ -1991,7 +1991,7 @@ as_hidden():
u'<input type="text" name="message" />' u'<input type="text" name="message" />'
>>> f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False) >>> f = ContactForm({'subject': 'Hello', 'message': 'I love you.'}, auto_id=False)
>>> f['subject'].as_textarea() >>> f['subject'].as_textarea()
u'<textarea name="subject">Hello</textarea>' u'<textarea rows="10" cols="40" name="subject">Hello</textarea>'
>>> f['message'].as_text() >>> f['message'].as_text()
u'<input type="text" name="message" value="I love you." />' u'<input type="text" name="message" value="I love you." />'
>>> f['message'].as_hidden() >>> f['message'].as_hidden()