Code

Ticket #11251: au-models.2.diff

File au-models.2.diff, 8.5 KB (added by DrMeers, 4 years ago)

models, forms, tests and documentation

Line 
1Index: django/contrib/localflavor/au/models.py
2===================================================================
3--- django/contrib/localflavor/au/models.py     (revision 0)
4+++ django/contrib/localflavor/au/models.py     (revision 0)
5@@ -0,0 +1,43 @@
6+from django.conf import settings
7+from django.utils.translation import ugettext_lazy as _
8+from django.db.models.fields import CharField
9+from django.contrib.localflavor.au.au_states import STATE_CHOICES
10+from django.contrib.localflavor.au import forms
11+
12+class AUStateField(CharField):
13+
14+    description = _("Australian State")
15+
16+    def __init__(self, *args, **kwargs):
17+        kwargs['choices'] = STATE_CHOICES
18+        kwargs['max_length'] = 3
19+        super(AUStateField, self).__init__(*args, **kwargs)
20+
21+
22+class AUPostCodeField(CharField):
23+
24+    description = _("Australian Postcode")
25+
26+    def __init__(self, *args, **kwargs):
27+        kwargs['max_length'] = 4
28+        super(AUPostCodeField, self).__init__(*args, **kwargs)
29+
30+    def formfield(self, **kwargs):
31+        defaults = {'form_class': forms.AUPostCodeField}
32+        defaults.update(kwargs)
33+        return super(AUPostCodeField, self).formfield(**defaults)
34+       
35+       
36+class AUPhoneNumberField(CharField):
37+
38+    description = _("Australian Phone number")
39+
40+    def __init__(self, *args, **kwargs):
41+        kwargs['max_length'] = 20
42+        super(AUPhoneNumberField, self).__init__(*args, **kwargs)
43+
44+    def formfield(self, **kwargs):
45+        defaults = {'form_class': forms.AUPhoneNumberField}
46+        defaults.update(kwargs)
47+        return super(AUPhoneNumberField, self).formfield(**defaults)
48+   
49Index: django/contrib/localflavor/au/forms.py
50===================================================================
51--- django/contrib/localflavor/au/forms.py      (revision 12761)
52+++ django/contrib/localflavor/au/forms.py      (working copy)
53@@ -12,15 +12,22 @@
54 PHONE_DIGITS_RE = re.compile(r'^(\d{10})$')
55 
56 class AUPostCodeField(RegexField):
57-    """Australian post code field."""
58+    """ Australian post code field.
59+
60+    Assumed to be 4 digits.
61+    Northern Territory 3-digit postcodes should have leading zero.
62+    """
63     default_error_messages = {
64-        'invalid': _('Enter a 4 digit post code.'),
65+        'invalid': _('Enter a 4 digit postcode.'),
66     }
67 
68     def __init__(self, *args, **kwargs):
69+        if 'max_length' in kwargs:
70+            kwargs.pop('max_length')
71         super(AUPostCodeField, self).__init__(r'^\d{4}$',
72-            max_length=None, min_length=None, *args, **kwargs)
73+            max_length=4, min_length=None, *args, **kwargs)
74 
75+       
76 class AUPhoneNumberField(Field):
77     """Australian phone number field."""
78     default_error_messages = {
79@@ -40,6 +47,7 @@
80             return u'%s' % phone_match.group(1)
81         raise ValidationError(self.error_messages['invalid'])
82 
83+   
84 class AUStateSelect(Select):
85     """
86     A Select widget that uses a list of Australian states/territories as its
87Index: tests/regressiontests/localflavor/tests.py
88===================================================================
89--- tests/regressiontests/localflavor/tests.py  (revision 12761)
90+++ tests/regressiontests/localflavor/tests.py  (working copy)
91@@ -1,7 +1,12 @@
92 from django.test import TestCase
93 from models import Place
94-from forms import PlaceForm
95+from forms import PlaceForm, AustralianPlaceForm
96+import re
97 
98+SELECTED_OPTION_PATTERN = r'<option value="%s" selected="selected">'
99+BLANK_OPTION_PATTERN = r'<option value="">'
100+INPUT_VALUE_PATTERN = r'<input[^>]*value="%s"[^>]*>'
101+
102 class USLocalflavorTests(TestCase):
103     def setUp(self):
104         self.form = PlaceForm({'state':'GA', 'state_req':'NC', 'name':'impossible'})
105@@ -81,3 +86,53 @@
106 <option value="WY">Wyoming</option>
107 </select>"""
108         self.assertEqual(str(self.form['state']), state_select_html)
109+
110+       
111+class AULocalflavorTests(TestCase):
112+    def setUp(self):
113+        self.form = AustralianPlaceForm(
114+            {'state':'WA',
115+             'state_required':'QLD',
116+             'name':'dummy',
117+             'postcode':'1234',
118+             'postcode_required':'4321',
119+             })
120+       
121+    def test_get_display_methods(self):
122+        """ Ensure get_*_display() methods are added to model instances. """
123+        place = self.form.save()
124+        self.assertEqual(place.get_state_display(), 'Western Australia')
125+        self.assertEqual(place.get_state_required_display(), 'Queensland')
126+
127+    def test_default_values(self):
128+        """ Ensure that default values are selected in forms. """
129+        form = AustralianPlaceForm()
130+        self.assertTrue(re.search(SELECTED_OPTION_PATTERN % 'NSW',
131+                                  str(form['state_default'])))
132+        self.assertTrue(re.search(INPUT_VALUE_PATTERN % '2500',
133+                                  str(form['postcode_default'])))
134+       
135+    def test_required(self):
136+        """ Test that required AUStateFields throw appropriate errors. """
137+        form = AustralianPlaceForm({'state':'NSW', 'name':'Wollongong'})
138+        self.assertFalse(form.is_valid())
139+        self.assertEqual(
140+            form.errors['state_required'], [u'This field is required.'])
141+        self.assertEqual(
142+            form.errors['postcode_required'], [u'This field is required.'])       
143+   
144+    def test_field_blank_option(self):
145+        """ Test that the empty option is there. """
146+        self.assertTrue(re.search(BLANK_OPTION_PATTERN,
147+                                  str(self.form['state'])))
148+
149+    def test_selected_values(self):
150+        """ Ensure selected states match the initial values provided. """
151+        self.assertTrue(re.search(SELECTED_OPTION_PATTERN % 'WA',
152+                                  str(self.form['state'])))
153+        self.assertTrue(re.search(SELECTED_OPTION_PATTERN % 'QLD',
154+                                  str(self.form['state_required'])))
155+        self.assertTrue(re.search(INPUT_VALUE_PATTERN % '1234',
156+                                  str(self.form['postcode'])))
157+        self.assertTrue(re.search(INPUT_VALUE_PATTERN % '4321',
158+                                  str(self.form['postcode_required'])))               
159Index: tests/regressiontests/localflavor/models.py
160===================================================================
161--- tests/regressiontests/localflavor/models.py (revision 12761)
162+++ tests/regressiontests/localflavor/models.py (working copy)
163@@ -1,8 +1,19 @@
164 from django.db import models
165 from django.contrib.localflavor.us.models import USStateField
166+from django.contrib.localflavor.au.models import AUStateField, AUPostCodeField
167 
168 class Place(models.Model):
169     state = USStateField(blank=True)
170     state_req = USStateField()
171     state_default = USStateField(default="CA", blank=True)
172     name = models.CharField(max_length=20)
173+
174+
175+class AustralianPlace(models.Model):
176+    state = AUStateField(blank=True)
177+    state_required = AUStateField()
178+    state_default = AUStateField(default="NSW", blank=True)
179+    postcode = AUPostCodeField(blank=True)
180+    postcode_required = AUPostCodeField()
181+    postcode_default = AUPostCodeField(default="2500", blank=True)
182+    name = models.CharField(max_length=20)
183Index: tests/regressiontests/localflavor/forms.py
184===================================================================
185--- tests/regressiontests/localflavor/forms.py  (revision 12761)
186+++ tests/regressiontests/localflavor/forms.py  (working copy)
187@@ -1,7 +1,12 @@
188 from django.forms import ModelForm
189-from models import Place
190+from models import Place, AustralianPlace
191 
192 class PlaceForm(ModelForm):
193     """docstring for PlaceForm"""
194     class Meta:
195         model = Place
196+
197+class AustralianPlaceForm(ModelForm):
198+    """ Form for storing an Australian place. """
199+    class Meta:
200+        model = AustralianPlace       
201Index: docs/ref/contrib/localflavor.txt
202===================================================================
203--- docs/ref/contrib/localflavor.txt    (revision 12761)
204+++ docs/ref/contrib/localflavor.txt    (working copy)
205@@ -169,6 +169,21 @@
206     A ``Select`` widget that uses a list of Australian states/territories as its
207     choices.
208 
209+.. class:: au.models.AUPhoneNumberField
210+
211+    A model field that checks that the value is a valid Australian phone
212+    number (ten digits).
213+
214+.. class:: au.models.AUStateField
215+
216+    A model field that forms represent as a ``forms.AUStateField`` field and
217+    stores the three-letter Australian state abbreviation in the database.
218+
219+.. class:: au.models.AUPostCodeField
220+
221+    A model field that forms represent as a ``forms.AUPostCodeField`` field
222+    and stores the four-digit Australian postcode in the database.
223+
224 Austria (``at``)
225 ================
226