3

I have added a custom backend to allow a user to log in with a username or email in addition to password. It works fine except when the email is longer than 30 characters. The form error I get is:

"Ensure this value has at most 30 characters (it has 35)." 

In one my my apps' urls.py file I've overridden the max_length of the username field like this:

from django.contrib.auth.forms import AuthenticationForm AuthenticationForm.base_fields['username'].max_length = 75 

I've even tried the class_prepared signal technique described here:

http://stackoverflow.com/questions/2610088/can-djangos-auth-user-username-be-varchar75-how-could-that-be-done/2613385#2613385 

I'm not sure where I'm going wrong here and I appreciate the help.

1
  • Have you made sure that the username field in the database can hold strings longer than 30 chars? The class_prepare signal will only help before you have run syncdb and created the table. Syncdb never alters existing tables. Commented Nov 6, 2010 at 6:09

3 Answers 3

4

If your aim is to simply alter the length of the username field for the form (and not to alter the length of the username field in the database), then the correct solution is to subclass AuthenticationForm like so:

from django import forms from django.contrib.auth.forms import AuthenticationForm class MyAuthenticationForm(AuthenticationForm): username = forms.CharField(label="Username", max_length=75) 

In fact, the docstring for AuthenticationForm even says "Base class for authenticating users. Extend this to get a form that accepts username/password logins."

Use your new form in place of the old AuthenticationForm in your templates, views, etc.

As for why your code isn't working, my guess is that your app's urls.py isn't being loaded before the AuthenticationForm is being imported elsewhere. I couldn't swear to that being the reason, but it's the most likely.

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

2 Comments

That works great! And the subclassed form can be passed to the login view, so I'm all set. Thanks.
Are you guys using django-registration? If so, where did you put the above code? Right now the login form is being auto-generated through that, so i'm not sure where to replace that with this
0

My guess: on urls.py use:

from django.contrib.auth.views import login ... (r'^accounts/login/$', login), 

instead of the "lazy evaluation" form:

(r'^accounts/login/$', 'django.contrib.auth.views.login'), 

Comments

0

Best way is this code added to the top level init:

# Added so the login field can take email addresses longer than 30 characters from django.contrib.auth.forms import AuthenticationForm AuthenticationForm.base_fields['username'].max_length = 75 AuthenticationForm.base_fields['username'].widget.attrs['maxlength'] = 75 AuthenticationForm.base_fields['username'].validators[0].limit_value = 75 

However, if you choose to us @Gabriel Hurley answer above, you can pass it to the login form by using the following code:

(r'^accounts/login/$', 'django.contrib.auth.views.login', { 'authentication_form': AuthenticationForm }), 

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.