Skip to content
Snippets Groups Projects
fields.py 2.01 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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}
    
    ADDRESS_FIELDS_ORDER = [
    
        "thoroughfare",
        "premise",
        "localityname",
        "administrativearea",
        "postalcode",
        "country",
    
        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):
    
        """
        The field stores the address in a flattened form,
        so the locality components are on the same level as country or premise
        """
    
        data = VALIDATION_DATA
    
    
        def clean(self, value, **kwargs):
    
                country_data = self.data[country]
    
                raise ValidationError("Invalid country selected") from None
    
            fields = flatten_data(country_data["fields"])
    
            missing_fields = set(country_data["required"]) - {
                field for field, value in value.items() if value
            }
    
                missing_field_name = [fields[field]["label"] for field in missing_fields]
                raise ValidationError(
                    "Please provide data for: {}".format(", ".join(missing_field_name))
                )
    
            return super().clean(value, **kwargs)
    
        def to_python(self, value):
            return json.dumps(value)
    
        def prepare_value(self, value):
            try:
    
                # Handle empty value with "or".
                return json.loads(value or {})
    
            except TypeError:
                return value