django-allauth icon indicating copy to clipboard operation
django-allauth copied to clipboard

ACCOUNT_USERNAME_VALIDATORS: path versus list

Open pennersr opened this issue 7 years ago • 9 comments

See: https://github.com/pennersr/django-allauth/pull/1648

pennersr avatar Mar 05 '17 12:03 pennersr

I responded to a closed ticket about an issue I have with the username validators. I'm not quite sure how to implement the solution correctly.

Details are in https://github.com/pennersr/django-allauth/pull/1648

biddellns avatar Mar 12 '17 22:03 biddellns

I came to conclusion this is a bug. Here my solution not sure how to apply this: I just hacked "account/app_settings.py"

Line 298

    @property
    def USERNAME_VALIDATORS(self):
        from django.core.exceptions import ImproperlyConfigured
        from allauth.utils import import_attribute
        from allauth.utils import get_user_model

        validators = self._setting('USERNAME_VALIDATORS', None)
        ret = []
        if validators:
            if not isinstance(validators, list):
                raise ImproperlyConfigured(
                    'ACCOUNT_USERNAME_VALIDATORS is expected to be a list')
            for validator in validators:
                ret.append(import_attribute(validator))
        else:
            if self.USER_MODEL_USERNAME_FIELD is not None:
                ret = get_user_model()._meta.get_field(
                    self.USER_MODEL_USERNAME_FIELD).validators
        return ret

arsen-movsesyan avatar Feb 24 '18 22:02 arsen-movsesyan

Not exactly a bug but still awkward. For reference if you found this by googling:

Create a custom validator like this:

class UserNameValidator():
    """ Validate username to be alpha numeric and ascii only.
    Pass this class to ACCOUNT_USERNAME_VALIDATORS
    See https://django-allauth.readthedocs.io/en/latest/configuration.html
    """

    def __call__(self, username="", *args, **kwargs):
        valid = username.isalnum() and username.isascii()
        if not valid:
            raise ValidationError(_("Only alphanumeric characters are allowed"))

# KLUDGE: instantiate a list of validators
# See https://github.com/pennersr/django-allauth/pull/1648#issuecomment-284223497
customvalidators = [UserNameValidator()]

Now in settings.py:

ACCOUNT_USERNAME_VALIDATORS = 'my_app.models.user.customvalidators'

squio avatar May 05 '21 10:05 squio

customvalidators 

Thank you @squio for your answer it did work for me flawlessly note : for the future do not forget about the import `from django.utils.translation import gettext_lazy as _

from django.core.exceptions import ValidationError`

escaper01 avatar Aug 13 '21 14:08 escaper01

close as fixed??

derek-adair avatar Sep 12 '23 11:09 derek-adair

No, that got reverted https://github.com/pennersr/django-allauth/pull/1648#issuecomment-284223497

pennersr avatar Sep 12 '23 18:09 pennersr

Is this a design decision? Or does this just need some documentation?

It seems like this comment is how a user should be implementing custom validators.

derek-adair avatar Sep 13 '23 12:09 derek-adair

Not really. Currently it is a path (str) pointing to a list, and documented as such. A change was proposed to turn that into a list of paths, but that breaks backwards compatibility. So, what could be done is to support both... it's a really minor thing.

pennersr avatar Sep 13 '23 15:09 pennersr

I have:

In settings.py ACCOUNT_USERNAME_VALIDATORS = 'main.validators.custom_username_validators'

And in that path: custom_username_validators = [ ... ]

where the signature of the function call for each is simply:

def validate_username_length(value):
    """ foo """
    if len(value) < 8:
        raise ValidationError("Username must be at least 8 characters long.")

.. and its exactly what we need to allow extension.

duaneking avatar Oct 08 '23 02:10 duaneking