From 78d852a6595d0e45def2da43d498249e39d24982 Mon Sep 17 00:00:00 2001 From: Todd Dembrey <todd.dembrey@torchbox.com> Date: Thu, 1 Feb 2018 10:40:23 +0000 Subject: [PATCH] Implement a AddressField to incorporate backend clean methods --- addressfield/fields.py | 47 ++++++++++++++++++++++++++++++++++ opentech/apply/funds/blocks.py | 5 ++-- 2 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 addressfield/fields.py diff --git a/addressfield/fields.py b/addressfield/fields.py new file mode 100644 index 000000000..1420c2529 --- /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 981717d57..11b0fc31d 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') -- GitLab