Pur*_*ell 65 django django-models django-authentication
这有什么错上运行ALTER TABLE auth_user做username是varchar(75)因此它可以适应的电子邮件?如果有什么事情会破坏什么?
如果您要更改auth_user.username为varchar(75)您需要修改django的位置?这只是在源代码中改变30到75的问题吗?
username = models.CharField(_('username'), max_length=30, unique=True, help_text=_("Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters"))
Run Code Online (Sandbox Code Playgroud)
或者这个领域是否还有其他验证需要更改或其他任何后果?
请参阅下面与bartek的评论讨论,了解这样做的原因.
编辑:经过几个月的回顾.对于不了解前提的人:某些应用程序没有要求或希望使用用户名,他们只使用电子邮件进行注册和验证.不幸的是,在django auth.contrib中,用户名是必需的.您可以开始在用户名字段中添加电子邮件,但该字段只有30个字符,而现实世界中的电子邮件可能很长.可能比这里建议的75个字符更长,但75个字符可以容纳最理智的电子邮件地址.问题针对的是这种情况,正如基于电子邮件授权的应用程序所遇到的那样.
Clé*_*ent 78
有一种方法可以在不触及核心模型的情况下实现这一目标,并且没有继承,但它肯定是hackish,我会特别小心地使用它.
如果你看一下Django 关于信号的文档,你会看到有一个被调用的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)
Run Code Online (Sandbox Code Playgroud)
那就行了.
但是有一些注意事项:
help_text字段,以反映新的最大长度UserChangeForm,UserCreationForm并且AuthenticationForm最大长度不是从模型字段推断出来的,而是直接在表单字段声明中推断出来.如果您使用的是South,则可以创建以下迁移以更改基础数据库中的列:
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
Run Code Online (Sandbox Code Playgroud)
sko*_*zen 25
基于Clément和Matt Miller上面的综合答案,我已经整合了一个实现它的快速应用程序.Pip安装,迁移和转发.将此作为评论,但还没有信誉!
https://github.com/GoodCloud/django-longer-username
编辑2014-12-08
以上模块现已弃用,以支持https://github.com/madssj/django-longer-username-and-email
Ros*_*ost 21
更新了Django 1.3版本的解决方案(无需修改manage.py):
创建新的django-app:
monkey_patch/
__init__.py
models.py
Run Code Online (Sandbox Code Playgroud)
首先安装它:(settings.py)
INSTALLED_APPS = (
'monkey_patch',
#...
)
Run Code Online (Sandbox Code Playgroud)
这是models.py:
from django.contrib.auth.models import User
from django.core.validators import MaxLengthValidator
NEW_USERNAME_LENGTH = 300
def monkey_patch_username():
username = User._meta.get_field("username")
username.max_length = NEW_USERNAME_LENGTH
for v in username.validators:
if isinstance(v, MaxLengthValidator):
v.limit_value = NEW_USERNAME_LENGTH
monkey_patch_username()
Run Code Online (Sandbox Code Playgroud)
上面的解决方案确实似乎更新了模型长度.但是,要在管理中反映您的自定义长度,您还需要覆盖管理表单(令人沮丧的是,它们不会简单地从模型继承长度).
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
UserChangeForm.base_fields['username'].max_length = NEW_USERNAME_LENGTH
UserChangeForm.base_fields['username'].widget.attrs['maxlength'] = NEW_USERNAME_LENGTH
UserChangeForm.base_fields['username'].validators[0].limit_value = NEW_USERNAME_LENGTH
UserChangeForm.base_fields['username'].help_text = UserChangeForm.base_fields['username'].help_text.replace('30', str(NEW_USERNAME_LENGTH))
UserCreationForm.base_fields['username'].max_length = NEW_USERNAME_LENGTH
UserCreationForm.base_fields['username'].widget.attrs['maxlength'] = NEW_USERNAME_LENGTH
UserCreationForm.base_fields['username'].validators[0].limit_value = NEW_USERNAME_LENGTH
UserCreationForm.base_fields['username'].help_text = UserChangeForm.base_fields['username'].help_text.replace('30', str(NEW_USERNAME_LENGTH))
Run Code Online (Sandbox Code Playgroud)