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
dja开发者_如何学JAVAngo.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
.
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)
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
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()
精彩评论