django / django-localflavor

Country-specific Django helpers, formerly of contrib fame
https://django-localflavor.readthedocs.io/
BSD 3-Clause "New" or "Revised" License
835 stars 292 forks source link

French local : Use class Validators for SIRET and SIREN model fields, do not format output #473

Open LLyaudet opened 2 years ago

LLyaudet commented 2 years ago

Hello,

Right now the SIRET and SIREN model fields use SIRET and SIREN form fields that do the validation. I prefer the architecture of the IBAN and BIC fields in generic that use class Validators, since you can call the validators without using form fields. Would you accept if I submit a PR with a new file validators.py in fr/ and add in it SIRENValidator and SIRETValidator classes ? I would use them as is done for IBANValidator and BICValidator.

There is also an annoying thing : SIRET is max length 14 but it is formatted with spaces. Thus if in Django admin you modify a form with a valid SIRET in it you get this error : "Ensure this value has at most 14 characters (it has 17)." image I don't know what is the nicest way to avoid this :

Thanks, best regards, Laurent Lyaudet

LLyaudet commented 2 years ago

For the annoying formatting, I have found a workaround : https://stackoverflow.com/questions/61896109/changing-max-length-on-a-charfield-for-a-modelform

class MyModelForm(forms.ModelForm):
    siret = FRSIRETField(max_length=17)
LLyaudet commented 2 years ago

If you want to keep some arguments from the model, the workaround is more complicated (and ugly) :

class MyModelForm(forms.ModelForm):
    # siret = FRSIRETField(max_length=17) will not work with blank=True

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields["siret"].max_length = 17
        for i, validator in enumerate(self.fields["siret"].validators):
            if isinstance(validator, MaxLengthValidator):
                self.fields["siret"].validators[i] = MaxLengthValidator(17)
                break
        self.fields["siret"].widget.attrs["maxlength"] = 17