diff --git a/addressfield/fields.py b/addressfield/fields.py new file mode 100644 index 0000000000000000000000000000000000000000..1420c25296f3c0765364b7bd64cef4569bef5775 --- /dev/null +++ b/addressfield/fields.py @@ -0,0 +1,47 @@ +import json +from os import path + +from django import forms +from django.core.exceptions import ValidationError + +from .widgets import AddressWidget + + +basepath = path.dirname(__file__) +filepath = path.abspath(path.join(basepath, "static", "addressfield.min.json")) +with open(filepath, encoding='utf8') as address_data: + countries = json.load(address_data)['options'] + +VALIDATION_DATA = {country['iso']: country for country in countries} + + +def flatten_data(data): + flattened = dict() + for d in data: + for k, v in d.items(): + if isinstance(v, list): + value = flatten_data(v) + else: + value = {k: v} + flattened.update(value) + return flattened + + +class AddressField(forms.CharField): + widget = AddressWidget + + def clean(self, value, **kwargs): + country = value['country'] + try: + country_data = VALIDATION_DATA[country] + except KeyError: + raise ValidationError('Invalid country selected') + + fields = flatten_data(country_data['fields']) + + missing_fields = set(country_data['required']) - set(value.keys()) + if missing_fields: + missing_field_name = [fields[field]['label'] for field in missing_fields] + raise ValidationError('Please provide data for: {}'.format(', '.join(missing_field_name))) + + super().clean(value, **kwargs) diff --git a/opentech/apply/funds/blocks.py b/opentech/apply/funds/blocks.py index 981717d57f5d68d74865fa9518e047386474fcdb..11b0fc31d7a0c1a3a894758cdd32790034b1dc4c 100644 --- a/opentech/apply/funds/blocks.py +++ b/opentech/apply/funds/blocks.py @@ -16,7 +16,7 @@ from opentech.apply.stream_forms.blocks import ( TextFieldBlock, ) from opentech.apply.categories.blocks import CategoryQuestionBlock -from addressfield.widgets import AddressWidget +from addressfield.fields import AddressField def find_duplicates(items): @@ -165,7 +165,8 @@ class EmailBlock(MustIncludeFieldBlock): class AddressFieldBlock(MustIncludeFieldBlock): name = 'address' description = 'The postal address of the user' - widget = AddressWidget + + field_class = AddressField class Meta: label = _('Address')