Skip to content

Commit cf484b4

Browse files
authored
Allow formatted IBANs longer than 26 chars to be saved (#522)
1 parent ad22c1c commit cf484b4

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

docs/changelog.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ Modifications to existing flavors:
7878
- `NPZoneSelect`: dandaki was corrected to gandaki (fixed typo).
7979

8080
(`gh-506 <https://github.com/django/django-localflavor/pull/506/files>`_).
81-
81+
- Allow formatted IBANs longer than 26 chars to be saved in `IBANField`
82+
(`gh-522 <https://github.com/django/django-localflavor/pull/522>`_).
8283

8384
Other changes:
8485

localflavor/generic/forms.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
'%d/%m/%y', # '25/10/06'
2323
)
2424

25-
IBAN_MIN_LENGTH = min(IBAN_COUNTRY_CODE_LENGTH.values())
26-
2725

2826
class DateField(forms.DateField):
2927
"""A date input field which uses non-US date input formats by default."""
@@ -80,11 +78,15 @@ class MyForm(forms.Form):
8078
"""
8179

8280
def __init__(self, use_nordea_extensions=False, include_countries=None, **kwargs):
83-
kwargs.setdefault('min_length', IBAN_MIN_LENGTH)
84-
kwargs.setdefault('max_length', 34)
81+
# The IBANValidator handles the length check, so we don't need to use the form min and max length validators.
82+
kwargs.pop("max_length", None)
8583
self.default_validators = [IBANValidator(use_nordea_extensions, include_countries)]
8684
super().__init__(**kwargs)
8785

86+
# We still need to use max_length=42 in the <input ...> instead of max_length=34 (from the model) to
87+
# account for the spaces in the formatted value.
88+
self.widget.attrs["max_length"] = 42
89+
8890
def to_python(self, value):
8991
value = super().to_python(value)
9092
if value in self.empty_values:

tests/test_generic/tests.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,8 @@ def test_iban_fields(self):
180180
'NL91ABNB0417164300': ['Not a valid IBAN.'],
181181
'NL91 ABNB 0417 1643 00': ['Not a valid IBAN.'],
182182

183-
'MU17BOMM0101101030300200000MUR12345': [
184-
'MU IBANs must contain 30 characters.',
185-
'Ensure this value has at most 34 characters (it has 35).'],
186-
'MU17 BOMM 0101 1010 3030 0200 000M UR12 345': [
187-
'MU IBANs must contain 30 characters.',
188-
'Ensure this value has at most 34 characters (it has 35).'],
183+
'MU17BOMM0101101030300200000MUR12345': ['MU IBANs must contain 30 characters.'],
184+
'MU17 BOMM 0101 1010 3030 0200 000M UR12 345': ['MU IBANs must contain 30 characters.'],
189185

190186
# This IBAN should only be valid only if the Nordea extensions are turned on.
191187
'BJ11B00610100400271101192591': ['BJ is not a valid country code for IBAN.'],
@@ -203,6 +199,17 @@ def test_iban_fields(self):
203199
self.assertIsNone(iban_model_field.to_python(None))
204200

205201
# Invalid inputs for model field.
202+
203+
# The model field has max_length set which means the max length validator is used, unlike the form.
204+
invalid['MU17BOMM0101101030300200000MUR12345'] = [
205+
'MU IBANs must contain 30 characters.',
206+
'Ensure this value has at most 34 characters (it has 35).'
207+
]
208+
invalid['MU17 BOMM 0101 1010 3030 0200 000M UR12 345'] = [
209+
'MU IBANs must contain 30 characters.',
210+
'Ensure this value has at most 34 characters (it has 35).',
211+
]
212+
206213
for input, errors in invalid.items():
207214
with self.subTest(input=input, errors=errors):
208215
with self.assertRaises(ValidationError) as context_manager:
@@ -307,6 +314,20 @@ def test_model_field_deconstruct(self):
307314
with self.subTest(attr=attr):
308315
self.assertEqual(getattr(test_instance, attr), getattr(new_instance, attr))
309316

317+
def test_model_form_input_max_length(self):
318+
form = UseNordeaExtensionsForm({
319+
"iban": "RU03 0445 2522 5408 1781 0538 0913 1041 9",
320+
})
321+
self.assertEqual(None, form.fields["iban"].max_length)
322+
self.assertEqual(42, form.fields["iban"].widget.attrs["max_length"])
323+
324+
form.save() # Not validation error raised.
325+
326+
def test_form_field_input_max_length_without_model_form(self):
327+
form_field = IBANFormField()
328+
self.assertEqual(None, form_field.max_length)
329+
self.assertEqual(42, form_field.widget.attrs["max_length"])
330+
310331

311332
class BICTests(TestCase):
312333
def test_bic_validator(self):

0 commit comments

Comments
 (0)