diff --git a/docs/authors.rst b/docs/authors.rst index 2ab2cfb2b..9e1a44059 100644 --- a/docs/authors.rst +++ b/docs/authors.rst @@ -82,6 +82,7 @@ Authors * Kevin Ramirez Zavalza * László Ratskó * Lefteris Nikoltsios +* Lucas Dantas Gueiros * Luis Alberto Santana * Łukasz Langa * Luke Benstead diff --git a/docs/changelog.rst b/docs/changelog.rst index b2811adaf..bbaadc2ad 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -16,6 +16,9 @@ Modifications to existing flavors: - Fix Belarus passport field description punctuation (`gh-484 `_). +- Add min and max length to brazilian Postal Code form field +- Brazilian model fields CPF, CNPJ and PostalCode create correct form + field when used by DjangoModelForm Other changes: diff --git a/localflavor/br/forms.py b/localflavor/br/forms.py index 4fb6f4d23..48ceaa04c 100644 --- a/localflavor/br/forms.py +++ b/localflavor/br/forms.py @@ -25,8 +25,8 @@ class BRZipCodeField(CharField): More details at: https://github.com/django/django-localflavor/issues/334 """ - def __init__(self, **kwargs): - super().__init__(**kwargs) + def __init__(self, max_length=9, min_length=8, **kwargs): + super().__init__(max_length=max_length, min_length=min_length, **kwargs) self.validators.append(BRPostalCodeValidator()) diff --git a/localflavor/br/models.py b/localflavor/br/models.py index 1d06d2194..152f5fb27 100644 --- a/localflavor/br/models.py +++ b/localflavor/br/models.py @@ -3,10 +3,16 @@ from . import validators from .br_states import STATE_CHOICES +from . import forms class BRStateField(CharField): - """A model field for states of Brazil.""" + """ + A model field for states of Brazil. + + Forms represent it as a :class:`~localflavor.br.forms.BRStateSelect` field. + + """ description = _("State of Brazil (two uppercase letters)") @@ -25,6 +31,8 @@ class BRCPFField(CharField): """ A model field for the brazilian document named of CPF (Cadastro de Pessoa Física) + Forms represent it as a :class:`~localflavor.br.forms.BRCPFField` field. + .. versionadded:: 2.2 """ @@ -39,12 +47,20 @@ def __init__(self, *args, **kwargs): kwargs['max_length'] = 14 super().__init__(*args, **kwargs) self.validators.append(validators.BRCPFValidator()) + + def formfield(self, **kwargs): + defaults = {'form_class': forms.BRCPFField} + defaults.update(kwargs) + return super().formfield(**defaults) + class BRCNPJField(CharField): """ A model field for the brazilian document named of CNPJ (Cadastro Nacional de Pessoa Jurídica) + Forms represent it as a :class:`~localflavor.br.forms.BRCNPJField` field. + .. versionadded:: 2.2 """ @@ -55,11 +71,17 @@ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.validators.append(validators.BRCNPJValidator()) + def formfield(self, **kwargs): + defaults = {'form_class': forms.BRCNPJField} + defaults.update(kwargs) + return super().formfield(**defaults) class BRPostalCodeField(CharField): """ A model field for the brazilian zip code + Forms represent it as a :class:`~localflavor.br.forms.BRZipCOdeField` field. + .. versionadded:: 2.2 """ @@ -69,3 +91,8 @@ def __init__(self, *args, **kwargs): kwargs['max_length'] = 9 super().__init__(*args, **kwargs) self.validators.append(validators.BRPostalCodeValidator()) + + def formfield(self, **kwargs): + defaults = {'form_class': forms.BRZipCodeField} + defaults.update(kwargs) + return super().formfield(**defaults) diff --git a/tests/test_br/test_br.py b/tests/test_br/test_br.py index a1a3726ab..44067cd4f 100644 --- a/tests/test_br/test_br.py +++ b/tests/test_br/test_br.py @@ -1,4 +1,4 @@ -from django.test import SimpleTestCase +from django.test import SimpleTestCase, TestCase from localflavor.br import models from localflavor.br.forms import (BRCNPJField, BRCPFField, BRProcessoField, BRStateChoiceField, BRStateSelect, @@ -16,18 +16,18 @@ def test_BRZipCodeField(self): '12345_123': error_format, '1234-123': error_format, 'abcde-abc': error_format, - '12345-': error_format, - '-123': error_format, + '12345-': ['Ensure this value has at least 8 characters (it has 6).'] + error_format, + '-123': ['Ensure this value has at least 8 characters (it has 4).'] + error_format, } self.assertFieldOutput(BRZipCodeField, valid, invalid) - for postal_code, _ in invalid.items(): + for postal_code, error in invalid.items(): form = BRPersonProfileForm({ 'postal_code': postal_code }) self.assertFalse(form.is_valid()) - self.assertEqual(form.errors['postal_code'], error_format) + self.assertEqual(form.errors['postal_code'], error) def test_BRCNPJField(self): error_format = { @@ -224,6 +224,37 @@ def test_model_form_valid(self): form = BRPersonProfileForm(case) self.assertTrue(form.is_valid()) +class BRLocalFlavorModelFormTests (TestCase): + def setUp(self): + self.form = BRPersonProfileForm({ + 'cpf':'111.111.111-11', + 'cnpj':'64-132-916/0001-88', + 'postal_code':'12345-123', + }) + + def test_BRCPFFiedlHtml(self): + name = 'cpf' + value = '111.111.111-11' + model_form_field = self.form.fields[name] + model_form_field_render = model_form_field.widget.render(name,value) + self.assertTrue('minlength="11"' in model_form_field_render) + self.assertTrue('maxlength="14"' in model_form_field_render) + + def test_BRCNPJFiedlHtml(self): + name = 'cnpj' + value = '64-132-916/0001-88' + model_form_field = self.form.fields[name] + model_form_field_render = model_form_field.widget.render(name,value) + self.assertTrue('minlength="14"' in model_form_field_render) + self.assertTrue('maxlength="18"' in model_form_field_render) + + def test_BRPostalCodeFiedlHtml(self): + name = 'postal_code' + value = '12345-123' + model_form_field = self.form.fields[name] + model_form_field_render = model_form_field.widget.render(name,value) + self.assertTrue('minlength="8"' in model_form_field_render) + self.assertTrue('maxlength="9"' in model_form_field_render) class BRLocalFlavorModelTests(SimpleTestCase):