3

I'm trying to make my admin login field greater than 30 characters because I'm using a custom Email Authentication backend that doesn't really care how long the username field is.

I wanted to set up a monkey_patch app that would apply the change to all admin sites.

from django.contrib.auth.forms import AuthenticationForm AuthenticationForm.base_fields['username'].max_length = 150 # or whatever 

It's not working and I don't see why not.

The print statements in...

  • django.contrib.admin.forms.AdminAuthenticationForm
  • django.contrib.auth.views.login
  • django.contrib.auth.views.login.form # instantiated form

... shows the correct, modified number when I render the login page via /myadmin/anywhere/.

Even the form instance in the final render function shows the correct number.

# django.contrib.auth.views.login ... print form.fields['username'].max_length # this is an instantiated form! return render_to_response(template_name, context ...) 

What am I missing?

Where is the field magically deciding to be 30 chars long? I don't see where it has a chance to change between my print statement and render_to_response.

If I pass the admin site a subclassed AuthenticationForm, it works.

class LongerAuthenticationForm(AuthenticationForm): username = forms.CharField(max_length=150) class MyAdmin(AdminSite): login_form = LongerAuthenticationForm 

This is all confusing to me because I can see that the form instance passed to the final render function has the correct CharField with max_length=150.

3 Answers 3

8

It looks like I need to modify the widget attrs directly.

I forgot that fields are instantiated once!
CharField(max_length=30) is already setting the widget attributes for the HTML. No matter how I change max_length on a field instance, the widget has already been generated.

Here's my solution in my monkey_patch app.

from django.contrib.auth.forms import AuthenticationForm AuthenticationForm.base_fields['username'].max_length = 150 # I guess not needed AuthenticationForm.base_fields['username'].widget.attrs['maxlength'] = 150 # html AuthenticationForm.base_fields['username'].validators[0].limit_value = 150 

I don't really understand why instantiating a new field instance doesn't work..?

AuthenticationForm.base_fields['username'] = forms.CharField(max_length=100) 
Sign up to request clarification or add additional context in comments.

Comments

3

In django 1.3 you can build an app with the following code and make sure you include it in the settings. Its a very similar solution to the accepted one but it extends from AdminAuthenticationForm, otherwise your non-field errors won't get displayed.

from django.contrib.admin.forms import AdminAuthenticationForm from django import forms from django.contrib.admin.sites import AdminSite class LongerAuthenticationForm(AdminAuthenticationForm): """ Subclass which extends the max length of the username field. """ username = forms.CharField(max_length=150) AdminSite.login_form = LongerAuthenticationForm 

Comments

1

from django.contrib.admin.forms import AdminAuthenticationForm

class ModifiedForm(AdminAuthenticationForm): username = forms.CharField(max_length=150) #and so on 

into urls.py

from django.contrib import admin admin.site.login_form = ModifiedForm ... admin.autodiscover() 

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.