Skip to content

Commit 102d326

Browse files
committed
Added support for empty_value kwarg in Django >= 1.11.
1 parent c5e40fc commit 102d326

40 files changed

+336
-247
lines changed

localflavor/ar/forms.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33

44
from __future__ import unicode_literals
55

6-
from django.core.validators import EMPTY_VALUES
76
from django.forms import ValidationError
87
from django.forms.fields import CharField, RegexField, Select
98
from django.utils.translation import ugettext_lazy as _
109

10+
from localflavor.compat import EmptyValueCompatMixin
11+
1112
from .ar_provinces import PROVINCE_CHOICES
1213

1314

@@ -18,7 +19,7 @@ def __init__(self, attrs=None):
1819
super(ARProvinceSelect, self).__init__(attrs, choices=PROVINCE_CHOICES)
1920

2021

21-
class ARPostalCodeField(RegexField):
22+
class ARPostalCodeField(EmptyValueCompatMixin, RegexField):
2223
"""
2324
A field that accepts a 'classic' NNNN Postal Code or a CPA.
2425
@@ -38,16 +39,16 @@ def __init__(self, max_length=8, min_length=4, *args, **kwargs):
3839

3940
def clean(self, value):
4041
value = super(ARPostalCodeField, self).clean(value)
41-
if value in EMPTY_VALUES:
42-
return ''
42+
if value in self.empty_values:
43+
return self.empty_value
4344
if len(value) not in (4, 8):
4445
raise ValidationError(self.error_messages['invalid'])
4546
if len(value) == 8:
4647
return '%s%s%s' % (value[0].upper(), value[1:5], value[5:].upper())
4748
return value
4849

4950

50-
class ARDNIField(CharField):
51+
class ARDNIField(EmptyValueCompatMixin, CharField):
5152
"""A field that validates 'Documento Nacional de Identidad' (DNI) numbers."""
5253

5354
default_error_messages = {
@@ -62,8 +63,8 @@ def __init__(self, max_length=10, min_length=7, *args, **kwargs):
6263
def clean(self, value):
6364
"""Value can be a string either in the [X]X.XXX.XXX or [X]XXXXXXX formats."""
6465
value = super(ARDNIField, self).clean(value)
65-
if value in EMPTY_VALUES:
66-
return ''
66+
if value in self.empty_values:
67+
return self.empty_value
6768
if not value.isdigit():
6869
value = value.replace('.', '')
6970
if not value.isdigit():
@@ -74,7 +75,7 @@ def clean(self, value):
7475
return value
7576

7677

77-
class ARCUITField(RegexField):
78+
class ARCUITField(EmptyValueCompatMixin, RegexField):
7879
"""
7980
This field validates a CUIT (Código Único de Identificación Tributaria).
8081
@@ -100,8 +101,8 @@ def __init__(self, max_length=None, min_length=None, *args, **kwargs):
100101
def clean(self, value):
101102
"""Value can be either a string in the format XX-XXXXXXXX-X or an 11-digit number."""
102103
value = super(ARCUITField, self).clean(value)
103-
if value in EMPTY_VALUES:
104-
return ''
104+
if value in self.empty_values:
105+
return self.empty_value
105106
value, cd = self._canon(value)
106107
if not value[:2] in ['27', '20', '30', '23', '24', '33']:
107108
raise ValidationError(self.error_messages['legal_type'])
@@ -132,7 +133,7 @@ def _format(self, cuit, check_digit=None):
132133
return '%s-%s-%s' % (cuit[:2], cuit[2:], check_digit)
133134

134135

135-
class ARCBUField(CharField):
136+
class ARCBUField(EmptyValueCompatMixin, CharField):
136137
"""
137138
This field validates a CBU (Clave Bancaria Uniforme).
138139
@@ -184,8 +185,8 @@ def _checksum(self, value):
184185
def clean(self, value):
185186
"""Value must be a 22 digits long number."""
186187
value = super(ARCBUField, self).clean(value)
187-
if value in EMPTY_VALUES:
188-
return ''
188+
if value in self.empty_values:
189+
return self.empty_value
189190
if not value.isdigit():
190191
raise ValidationError(self.error_messages['invalid'])
191192
if not self._checksum(value):

localflavor/au/forms.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44

55
import re
66

7-
from django.core.validators import EMPTY_VALUES
87
from django.forms import ValidationError
98
from django.forms.fields import CharField, RegexField, Select
109
from django.utils.encoding import force_text
1110
from django.utils.translation import ugettext_lazy as _
1211

12+
from localflavor.compat import EmptyValueCompatMixin
1313
from localflavor.generic.forms import DeprecatedPhoneNumberFormFieldMixin
1414

1515
from .au_states import STATE_CHOICES
@@ -35,7 +35,7 @@ def __init__(self, max_length=4, min_length=None, *args, **kwargs):
3535
max_length, min_length, *args, **kwargs)
3636

3737

38-
class AUPhoneNumberField(CharField, DeprecatedPhoneNumberFormFieldMixin):
38+
class AUPhoneNumberField(EmptyValueCompatMixin, CharField, DeprecatedPhoneNumberFormFieldMixin):
3939
"""
4040
A form field that validates input as an Australian phone number.
4141
@@ -49,8 +49,8 @@ class AUPhoneNumberField(CharField, DeprecatedPhoneNumberFormFieldMixin):
4949
def clean(self, value):
5050
"""Validate a phone number. Strips parentheses, whitespace and hyphens."""
5151
super(AUPhoneNumberField, self).clean(value)
52-
if value in EMPTY_VALUES:
53-
return ''
52+
if value in self.empty_values:
53+
return self.empty_value
5454
value = re.sub('(\(|\)|\s+|-)', '', force_text(value))
5555
phone_match = PHONE_DIGITS_RE.search(value)
5656
if phone_match:
@@ -65,7 +65,7 @@ def __init__(self, attrs=None):
6565
super(AUStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
6666

6767

68-
class AUBusinessNumberField(CharField):
68+
class AUBusinessNumberField(EmptyValueCompatMixin, CharField):
6969
"""
7070
A form field that validates input as an Australian Business Number (ABN).
7171
@@ -77,6 +77,8 @@ class AUBusinessNumberField(CharField):
7777

7878
def to_python(self, value):
7979
value = super(AUBusinessNumberField, self).to_python(value)
80+
if value in self.empty_values:
81+
return self.empty_value
8082
return value.upper().replace(' ', '')
8183

8284
def prepare_value(self, value):
@@ -88,7 +90,7 @@ def prepare_value(self, value):
8890
return '{} {} {} {}'.format(spaceless[:2], spaceless[2:5], spaceless[5:8], spaceless[8:])
8991

9092

91-
class AUCompanyNumberField(CharField):
93+
class AUCompanyNumberField(EmptyValueCompatMixin, CharField):
9294
"""
9395
A form field that validates input as an Australian Company Number (ACN).
9496
@@ -99,6 +101,8 @@ class AUCompanyNumberField(CharField):
99101

100102
def to_python(self, value):
101103
value = super(AUCompanyNumberField, self).to_python(value)
104+
if value in self.empty_values:
105+
return self.empty_value
102106
return value.upper().replace(' ', '')
103107

104108
def prepare_value(self, value):

localflavor/br/forms.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from django.utils.encoding import force_text
1212
from django.utils.translation import ugettext_lazy as _
1313

14+
from localflavor.compat import EmptyValueCompatMixin
1415
from localflavor.generic.forms import DeprecatedPhoneNumberFormFieldMixin
1516

1617
from .br_states import STATE_CHOICES
@@ -103,7 +104,7 @@ def DV_maker(v): # noqa
103104
return dv_maker(v)
104105

105106

106-
class BRCPFField(CharField):
107+
class BRCPFField(EmptyValueCompatMixin, CharField):
107108
"""
108109
A form field that validates a CPF number or a CPF string.
109110
@@ -124,8 +125,8 @@ def __init__(self, max_length=14, min_length=11, *args, **kwargs):
124125
def clean(self, value):
125126
"""Value can be either a string in the format XXX.XXX.XXX-XX or an 11-digit number."""
126127
value = super(BRCPFField, self).clean(value)
127-
if value in EMPTY_VALUES:
128-
return ''
128+
if value in self.empty_values:
129+
return self.empty_value
129130
orig_value = value[:]
130131
if not value.isdigit():
131132
cpf = cpf_digits_re.search(value)
@@ -153,7 +154,7 @@ def clean(self, value):
153154
return orig_value
154155

155156

156-
class BRCNPJField(CharField):
157+
class BRCNPJField(EmptyValueCompatMixin, CharField):
157158
"""
158159
A form field that validates input as `Brazilian CNPJ`_.
159160
@@ -183,8 +184,8 @@ def __init__(self, min_length=14, max_length=18, *args, **kwargs):
183184
def clean(self, value):
184185
"""Value can be either a string in the format XX.XXX.XXX/XXXX-XX or a group of 14 characters."""
185186
value = super(BRCNPJField, self).clean(value)
186-
if value in EMPTY_VALUES:
187-
return ''
187+
if value in self.empty_values:
188+
return self.empty_value
188189
orig_value = value[:]
189190
if not value.isdigit():
190191
cnpj = cnpj_digits_re.search(value)
@@ -213,7 +214,7 @@ def mod_97_base10(value):
213214
return 98 - ((value * 100 % 97) % 97)
214215

215216

216-
class BRProcessoField(CharField):
217+
class BRProcessoField(EmptyValueCompatMixin, CharField):
217218
"""
218219
A form field that validates a Legal Process(Processo) number or a Legal Process string.
219220
@@ -232,8 +233,8 @@ def __init__(self, max_length=25, min_length=20, *args, **kwargs):
232233
def clean(self, value):
233234
"""Value can be either a string in the format NNNNNNN-DD.AAAA.J.TR.OOOO or an 20-digit number."""
234235
value = super(BRProcessoField, self).clean(value)
235-
if value in EMPTY_VALUES:
236-
return ''
236+
if value in self.empty_values:
237+
return self.empty_value
237238

238239
orig_value = value[:]
239240
if not value.isdigit():

localflavor/ca/forms.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
from django.utils.encoding import force_text
1111
from django.utils.translation import ugettext_lazy as _
1212

13+
from localflavor.compat import EmptyValueCompatMixin
1314
from localflavor.generic.checksums import luhn
1415
from localflavor.generic.forms import DeprecatedPhoneNumberFormFieldMixin
1516

1617
phone_digits_re = re.compile(r'^(?:1-?)?(\d{3})[-\.]?(\d{3})[-\.]?(\d{4})$')
1718
sin_re = re.compile(r"^(\d{3})-(\d{3})-(\d{3})$")
1819

1920

20-
class CAPostalCodeField(CharField):
21+
class CAPostalCodeField(EmptyValueCompatMixin, CharField):
2122
"""
2223
Canadian postal code form field.
2324
@@ -36,8 +37,8 @@ class CAPostalCodeField(CharField):
3637

3738
def clean(self, value):
3839
value = super(CAPostalCodeField, self).clean(value)
39-
if value in EMPTY_VALUES:
40-
return ''
40+
if value in self.empty_values:
41+
return self.empty_value
4142
postcode = value.upper().strip()
4243
m = self.postcode_regex.match(postcode)
4344
if not m:

localflavor/cl/forms.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
from __future__ import unicode_literals
44

5-
from django.core.validators import EMPTY_VALUES
65
from django.forms import ValidationError
76
from django.forms.fields import RegexField, Select
87
from django.utils.encoding import force_text
98
from django.utils.translation import ugettext_lazy as _
109

10+
from localflavor.compat import EmptyValueCompatMixin
11+
1112
from .cl_regions import REGION_CHOICES
1213

1314

@@ -18,7 +19,7 @@ def __init__(self, attrs=None):
1819
super(CLRegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
1920

2021

21-
class CLRutField(RegexField):
22+
class CLRutField(EmptyValueCompatMixin, RegexField):
2223
"""
2324
Chilean "Rol Unico Tributario" (RUT) field.
2425
@@ -48,8 +49,8 @@ def __init__(self, *args, **kwargs):
4849
def clean(self, value):
4950
"""Check and clean the Chilean RUT."""
5051
super(CLRutField, self).clean(value)
51-
if value in EMPTY_VALUES:
52-
return ''
52+
if value in self.empty_values:
53+
return self.empty_value
5354
rut, verificador = self._canonify(value)
5455
if self._algorithm(rut) == verificador:
5556
return self._format(rut, verificador)

localflavor/cn/forms.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from django.forms.fields import CharField, RegexField, Select
99
from django.utils.translation import ugettext_lazy as _
1010

11+
from localflavor.compat import EmptyValueCompatMixin
1112
from localflavor.generic.forms import DeprecatedPhoneNumberFormFieldMixin
1213

1314
from .cn_provinces import CN_PROVINCE_CHOICES
@@ -87,7 +88,7 @@ def __init__(self, *args, **kwargs):
8788
super(CNPostCodeField, self).__init__(POST_CODE_RE, *args, **kwargs)
8889

8990

90-
class CNIDCardField(CharField):
91+
class CNIDCardField(EmptyValueCompatMixin, CharField):
9192
"""
9293
A form field that validates input as a Resident Identity Card (PRC) number.
9394
@@ -116,8 +117,8 @@ def clean(self, value):
116117
"""Check whether the input is a valid ID Card Number."""
117118
# Check the length of the ID card number.
118119
super(CNIDCardField, self).clean(value)
119-
if not value:
120-
return ""
120+
if value in self.empty_values:
121+
return self.empty_value
121122
# Check whether this ID card number has valid format
122123
if not re.match(ID_CARD_RE, value):
123124
raise ValidationError(self.error_messages['invalid'])

localflavor/compat.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
class EmptyValueCompatMixin(object):
3+
"""
4+
forms.CharField in Django >= 1.11 has an 'empty_value' keyword argument for representing a value for "empty".
5+
6+
https://docs.djangoproject.com/en/1.11/ref/forms/fields/#django.forms.CharField.empty_value
7+
8+
This mixin adds self.empty_value set to an empty string for Django <= 1.10. This allows localflavor form fields to
9+
use self.empty_value consistently across Django versions.
10+
11+
This mixin does not add an 'empty_value' keyword argument to versions of Django that don't already support it.
12+
13+
This mixin can be removed when localflavor removes support for Django <= 1.10.
14+
"""
15+
def __init__(self, *args, **kwargs):
16+
super(EmptyValueCompatMixin, self).__init__(*args, **kwargs)
17+
if not hasattr(self, 'empty_value'):
18+
self.empty_value = ''

localflavor/cz/forms.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from django.forms.fields import Field, RegexField, Select
1010
from django.utils.translation import ugettext_lazy as _
1111

12+
from localflavor.compat import EmptyValueCompatMixin
13+
1214
from .cz_regions import REGION_CHOICES
1315

1416
birth_number = re.compile(r'^(?P<birth>\d{6})/?(?P<id>\d{3,4})$')
@@ -22,7 +24,7 @@ def __init__(self, attrs=None):
2224
super(CZRegionSelect, self).__init__(attrs, choices=REGION_CHOICES)
2325

2426

25-
class CZPostalCodeField(RegexField):
27+
class CZPostalCodeField(EmptyValueCompatMixin, RegexField):
2628
"""
2729
A form field that validates its input as Czech postal code.
2830
@@ -43,8 +45,10 @@ def clean(self, value):
4345
4446
Returns an empty string for empty values.
4547
"""
46-
v = super(CZPostalCodeField, self).clean(value)
47-
return v.replace(' ', '')
48+
value = super(CZPostalCodeField, self).clean(value)
49+
if value in self.empty_values:
50+
return self.empty_value
51+
return value.replace(' ', '')
4852

4953

5054
class CZBirthNumberField(Field):

0 commit comments

Comments
 (0)