There's a way to achieve that without touching the core model, and without inheritance, but it's definitely hackish and I would use it with extra care.
If you look at Django's doc on signals, you'll see there's one called class_prepared
, which is basically sent once any actual model class has been created by the metaclass. That moment is your last chance of modifying any model before any magic takes place (ie: ModelForm
, ModelAdmin
, syncdb
, etc...).
So the plan is simple, you just register that signal with a handler that will detect when it is called for the User
model, and then change the max_length
property of the username
field.
Now the question is, where should this code lives? It has to be executed before the User
model is loaded, so that often means very early. Unfortunately, you can't (django 1.1.1, haven't check with another version) put that in settings
because importing signals
there will break things.
A better choice would be to put it in a dummy app's models module, and to put that app on top of the INSTALLED_APPS
list/tuple (so it gets imported before anything else). Here is an example of what you can have in myhackishfix_app/models.py
:
from django.db.models.signals import class_prepared
def longer_username(sender, *args, **kwargs):
# You can't just do `if sender == django.contrib.auth.models.User`
# because you would have to import the model
# You have to test using __name__ and __module__
if sender.__name__ == "User" and sender.__module__ == "django.contrib.auth.models":
sender._meta.get_field("username").max_length = 75
class_prepared.connect(longer_username)
That will do the trick.
A few notes though:
- You might want to change also the
help_text
of the field, to reflect the new maximum length
- If you want to use the automatic admin, you will have to subclass
UserChangeForm
and UserCreationForm
as the maximum length is not deduced from the model field, but directly in the form field declaration.