有一种方法可以在不接触核心模型且没有继承的情况下实现这一目标,但这绝对是hackish,我会格外小心地使用它。
如果你查看Django的关于 signal的文档,你会看到有一个名为的文档class_prepared,该文档基本上是在元类创建了任何实际的模型类之后发送的。那一刻是你修改任何型号的最后机会之前,任何神奇的发生(即:ModelForm
,ModelAdmin
,syncdb
,等…)。
因此,该计划很简单,你只需向处理程序注册该信号,该处理程序将检测何时为User
模型调用该信号,然后更改max_length
该username
字段的属性。
现在的问题是,该代码应该放在哪里?它必须在User加载模型之前执行,因此通常意味着很早。不幸的是,你不能(django 1.1.1,没有检查其他版本)将其放进去,settings
因为在signals
那儿导入会损坏东西。
更好的选择是将其放在虚拟应用程序的“模型”模块中,并将该应用程序放在INSTALLED_APPS列表/元组的顶部(这样就可以先导入它)。这是你可以拥有的示例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)
这样就可以了。
一些注意事项:
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