1

I'm using Django allauth as my user account framework for my django site. The docs show there is an ACCOUNT_USERNAME_MIN_LENGTH however there is no ACCOUNT_USERNAME_MAX_LENGTH for some reason.

Is there any way to create a max length for username?

Here's my custom allauth signup form - maybe I can do something here?:

class AllauthSignupForm(forms.Form): captcha = ReCaptchaField( public_key=config("RECAPTCHA_PUBLIC_KEY"), private_key=config("RECAPTCHA_PRIVATE_KEY"), ) class Meta: model = User def signup(self, request, user): """ Required, or else it throws deprecation warnings """ pass 

Edit: Trying to subclass SignupView

draft1/forms.py

class AllauthSignupForm(SignupForm): def __init__(self, *args, **kwargs): super(AllauthSignupForm, self).__init__(*args, **kwargs) self.fields['username']['validators'] += MaxLengthValidator(150, "Username should be less than 150 character long") captcha = ReCaptchaField( public_key=config("RECAPTCHA_PUBLIC_KEY"), private_key=config("RECAPTCHA_PRIVATE_KEY"), ) class Meta: model = User def signup(self, request, user): """ Required, or else it throws deprecation warnings """ pass 

draft1/views.py

from allauth.account.views import SignupView class MySignupView(SignupView): form_class = AllauthSignupForm 

allauth/account/urls.py

url(r"^signup/$", MySignupView.as_view(), name="account_signup"), 

draft1/settings.py

ACCOUNT_SIGNUP_FORM_CLASS = 'draft1.forms.AllauthSignupForm' 

The above code returns this error:

Traceback (most recent call last): File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/utils/autoreload.py", line 228, in wrapper fn(*args, **kwargs) File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/management/commands/runserver.py", line 125, in inner_run self.check(display_num_errors=True) File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/management/base.py", line 359, in check include_deployment_checks=include_deployment_checks, File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/management/base.py", line 346, in _run_checks return checks.run_checks(**kwargs) File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/checks/registry.py", line 81, in run_checks new_errors = check(app_configs=app_configs) File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/checks/urls.py", line 16, in check_url_config return check_resolver(resolver) File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/core/checks/urls.py", line 26, in check_resolver return check_method() File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/urls/resolvers.py", line 254, in check for pattern in self.url_patterns: File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__ res = instance.__dict__[self.name] = self.func(instance) File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/urls/resolvers.py", line 405, in url_patterns patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module) File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/utils/functional.py", line 35, in __get__ res = instance.__dict__[self.name] = self.func(instance) File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/django/urls/resolvers.py", line 398, in urlconf_module return import_module(self.urlconf_name) File "/Users/zorgan/Desktop/postr1/lib/python3.5/importlib/__init__.py", line 126, in import_module return _bootstrap._gcd_import(name[level:], package, level) File "<frozen importlib._bootstrap>", line 986, in _gcd_import File "<frozen importlib._bootstrap>", line 969, in _find_and_load File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 673, in _load_unlocked File "<frozen importlib._bootstrap_external>", line 665, in exec_module File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed File "/Users/zorgan/Desktop/vorsso/venvor/draft1/urls.py", line 6, in <module> from . import views File "/Users/zorgan/Desktop/vorsso/venvor/draft1/views.py", line 11, in <module> from .forms import UserSettingsForm File "/Users/zorgan/Desktop/vorsso/venvor/draft1/forms.py", line 8, in <module> from allauth.account.forms import SignupForm File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/allauth/account/forms.py", line 228, in <module> class BaseSignupForm(_base_signup_form_class()): File "/Users/zorgan/Desktop/postr1/lib/python3.5/site-packages/allauth/account/forms.py", line 216, in _base_signup_form_class fc_classname)) django.core.exceptions.ImproperlyConfigured: Module "draft1.forms" does not define a "AllauthSignupForm" class 
1
  • 1
    I have created this pull request regarding adding ACCOUNT_USERNAME_MAX_LENGTH setting Commented Jun 2, 2018 at 11:27

5 Answers 5

3

This can be quickly done by extending DefaultAccountAdapter class and overriding the clean_username method. You need to also reference the clean_username once again after our custom validation to complete other inbuilt validations.

It can be done as follows.

from allauth.account.adapter import DefaultAccountAdapter from django.forms import ValidationError class UsernameMaxAdapter(DefaultAccountAdapter): def clean_username(self, username): if len(username) > 'Your Max Size': raise ValidationError('Please enter a username value less than the current one') return DefaultAccountAdapter.clean_username(self,username) # For other default validations. 

Finally, point to the subclass in your settings.py

ACCOUNT_ADAPTER = 'YourProject.adapter.UsernameMaxAdapter' 

Reference: https://github.com/pennersr/django-allauth/blob/8fbbf8c1d32832d72de5ed1c7fd77600af57ea6f/allauth/account/adapter.py#L244

Sign up to request clarification or add additional context in comments.

1 Comment

Thankyou so much! I've tried everything and this is the only thing that works and it is also very simple.
0

You should use a max length validator like below. More documentation about validators here.

from django.core.validators import MaxLengthValidator from allauth.account.forms import SignupForm class AllauthSignupForm(SignupForm): def __init__(self, *args, **kwargs): self.fields['username']['validators'] += MaxLengthValidator(150, "Username should be less than 150 character long") 

5 Comments

Tried that but getting this error 'SignupForm' object has no attribute 'fields' .. any idea?
Your form should extend allauth SignupForm like in my edited post.
Also I think you access username field with self.username
When I change forms.Form to SignupForm it gives this error: django.core.exceptions.ImproperlyConfigured: Module "draft1.forms" does not define a "AllauthSignupForm" class - any idea?
I think that you need to call the super __init__ first: super(AllauthSignupForm, self).__init__(*args, **kwargs) before to use the self.fields
0

Not sure if this is the best way but it works.

After extending the SignupForm, Completely changed the username field with a new one that has the max_length parameter.

from django import forms from django.utils.translation import ugettext_lazy as _ from allauth.account.forms import SignupForm class AllauthSignupForm(SignupForm): username = forms.CharField(label=_("Username"), min_length=5, max_length=20, # Change this widget=forms.TextInput( attrs={'placeholder': _('Username'), 'autofocus': 'autofocus'})) 

2 Comments

When I change forms.Form to SignupForm I get this error: django.core.exceptions.ImproperlyConfigured: Module "draft1.forms" does not define a "AllauthSignupForm" class - Any idea? I imported SignupForm aswell
0
+50

I would like to explain why there is no ACCOUNT_USERNAME_MAX_LENGTH. If you open source code you will see that max_length validator comes from username model field https://github.com/pennersr/django-allauth/blob/330bf899dd77046fd0510221f3c12e69eb2bc64d/allauth/account/forms.py#L277

username_field.max_length = get_username_max_length() 

Where get_username_max_length is function that actually pulls max_length value from User model https://github.com/pennersr/django-allauth/blob/8fbbf8c1d32832d72de5ed1c7fd77600af57ea6f/allauth/utils.py#L64

def get_username_max_length(): from .account.app_settings import USER_MODEL_USERNAME_FIELD if USER_MODEL_USERNAME_FIELD is not None: User = get_user_model() max_length = User._meta.get_field(USER_MODEL_USERNAME_FIELD).max_length else: max_length = 0 return max_length 

First approach: So you could change max_length value directly on your User's model username field if you have it swapped.

I don't think overriding form fields or __init__ method will actually work the it suggested by other answers, because assign of max_length happens in subclass of ACCOUNT_SIGNUP_FORM_CLASS https://github.com/pennersr/django-allauth/blob/330bf899dd77046fd0510221f3c12e69eb2bc64d/allauth/account/forms.py#L259

class BaseSignupForm(_base_signup_form_class()): 

where _base_signup_form_class is function that gets your ACCOUNT_SIGNUP_FORM_CLASS

Second approach: is to subclass SignupView and override it's SignupForm read Override signup view django-allauth and How to customize user profile when using django-allauth

In that SignupForm you could actually do what @MehdiB or @PeterSobhi suggested.

ImproperlyConfigured issue occurs because of https://github.com/pennersr/django-allauth/issues/1792

So you be sure that these forms are defined in different python modules as per https://github.com/pennersr/django-allauth/issues/1749#issuecomment-304628013

# base/forms.py # this is form that your ACCOUNT_SIGNUP_FORM_CLASS is points to class BaseSignupForm(forms.Form): captcha = ReCaptchaField( public_key=config("RECAPTCHA_PUBLIC_KEY"), private_key=config("RECAPTCHA_PRIVATE_KEY"), ) class Meta: model = User def signup(self, request, user): """ Required, or else it throws deprecation warnings """ pass # data1/forms.py # this is your signup form from django.core.validators import MaxLengthValidator from allauth.account.forms import SignupForm class MySignupForm(SignupForm): def __init__(self, *args, **kwargs): super(MySignupForm, self).__init__(*args, **kwargs) self.fields['username']['validators'] += MaxLengthValidator(150, "Username should be less than 150 character long") # views.py from allauth.account.views import SignupView class MySignupView(SignupView): form_class = MySignupForm # urls.py url(r"^signup/$", MySignupView.as_view(), name="account_signup"), 

7 Comments

Thanks for the suggestions. I tried the 2nd method but got a ImproperlyConfigured: Module "draft1.forms" does not define a "AllauthSignupForm" class error. Not sure why - I've added my code and the Traceback in the edit if you'd like to look.
Just tried that - there were no errors however it doesn't decrease max_length. My settings are ACCOUNT_SIGNUP_FORM_CLASS = 'draft1.forms.BaseSignupForm' and I ensured the 2 forms are in 2 different modules, but still doesn't work. Any idea why?
@Zorgan what database you are using?
I'm using postrgresql (psycopg2) as my database
@Zorgan Are you sure you are using overridden view instead of default one?
|
0

Try importing with the full name like in your forms : from allauth.accouts import forms as AllauthForms class AllauthSignupForm(AllauthForms.SignupForm): ....

i didn't test this and sorry i posted this with my phone i will reformat the answer soon

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.