Есть способ достичь этого, не затрагивая основную модель и не наследуя, но он определенно хакерский, и я бы использовал его с особой осторожностью.
Если вы посмотрите на документ Django по сигналам , вы увидите, что есть документ под названием class_prepared
, который в основном отправляется после того, как метакласс создал настоящий класс модели. Этот момент - ваш последний шанс изменить любую модель до того, как произойдет любая магия (то есть: ModelForm
, ModelAdmin
, syncdb
и т. Д.).
Таким образом, план прост: вы просто регистрируете этот сигнал с помощью обработчика, который определит, когда он вызывается для модели User
, а затем измените свойство max_length
поля username
.
Теперь вопрос в том, где должен жить этот код? Он должен быть выполнен до загрузки модели User
, так что это часто означает очень рано . К сожалению, вы не можете (django 1.1.1 , не проверять с другой версией) вставить это в settings
, потому что импорт signals
сломает вещи.
Лучшим вариантом было бы поместить его в модуль моделей фиктивного приложения и поместить это приложение поверх INSTALLED_APPS
list / tuple (чтобы оно импортировалось раньше всего). Вот пример того, что вы можете иметь в 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)
Это сработает.
Несколько замечаний:
- Вы можете также изменить
help_text
поля, чтобы отразить новую максимальную длину
- Если вы хотите использовать автоматического администратора, вам нужно будет создать подкласс
UserChangeForm
, UserCreationForm
и AuthenticationForm
, поскольку максимальная длина определяется не из поля модели, а непосредственно в объявлении поля формы.
Если вы используете Юг , вы можете создать следующую миграцию для изменения столбца в базовой базе данных:
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'User.username'
db.alter_column('auth_user', 'username', models.CharField(max_length=75))
def backwards(self, orm):
# Changing field 'User.username'
db.alter_column('auth_user', 'username', models.CharField(max_length=35))
models = {
# ... Copy the remainder of the file from the previous migration, being sure
# to change the value for auth.user / usename / maxlength