22

我需要增加 auth 中的最大用户名大小以超过模型中定义的 30 个字符。怎么做到呢?我不确定只是自定义模型是正确或安全的方法。

4

4 回答 4

12

这里的答案是一个有趣的方法: Can django's auth_user.username be varchar(75)? 那怎么可能呢?

syncdb一个覆盖 User 模型上的 max_length 属性的小应用程序,但请注意,如果未编辑表,则需要修改您的 DB 列

我个人使用修剪后的哈希作为我的用户名,如果发生极不可能的碰撞,它会通知我,主题为“你刚刚中了彩票!”

于 2011-01-14T19:52:05.723 回答
4

我在我们现有的基础设施中遇到了这种需求。

我们的整个后端都依赖于 Django 默认用户模型,但我们需要更改此 max_len 以使其与电子邮件 max_len 匹配。

从我看到的大多数 StackOverflow 帖子中,人们大多建议创建自定义用户模型。这绝对是我们需要避免的事情。当在生产中对数十万用户执行时,从默认用户模型更改为自定义模型是一项严肃而复杂的操作。

因此,相反,我们只想将更改直接应用到数据库模式本身。要正确执行此操作,最好的方法是从迁移中执行更改。但是,我看不到直接为 User 模型生成迁移的方法。

我可以看到的一种方法是生成一个空迁移,然后使用原始 SQL 来执行迁移。

生成空迁移:

python manage.py makemigrations YOUR_APP --empty

编辑迁移:

# -*- coding: utf-8 -*-
# Generated by Django 1.10.6 on 2019-02-11 09:39
from __future__ import unicode_literals

from django.db import migrations, models
from django.db.models import F
from django.db.models.functions import Length

from pittsburgh.models import User

#
# This function fixes thee existing user records by applying setting their username to be their email
#
def forwards_func_username(apps, schema_editor):
    User.objects.annotate(email_len=Length('email')).filter(email_len__gte=30).update(username=F('email'))

#
# This function reverts back to the original state
# Users with email > 30 chars have their username being a truncated email
#
def reverse_func_username(apps, schema_editor):
    users = User.objects.annotate(email_len=Length('email')).filter(email_len__gte=30)

    for user in users:
        user.username = user.email[:30]
        user.save()

class Migration(migrations.Migration):

    dependencies = [
        ('pittsburgh', '0076_auto_20190205_1623'),
    ]

    operations = [
        # change username max_length from 30 to 75 to match email max max_length
        migrations.RunSQL(sql="ALTER TABLE auth_user MODIFY COLUMN username VARCHAR(75) NOT NULL;",
                          reverse_sql="ALTER TABLE auth_user MODIFY COLUMN username VARCHAR(30) NOT NULL;"),
        # update username to match email
        migrations.RunPython(forwards_func_username, reverse_func_username),
    ]

forwards_func_usernamereverse_func_usernameof是可选的RunPython,取决于你愿意做什么。

请注意,RunSQL需要sqlparse依赖项,因此不要忘记将其添加到您的requirements.txt文件中。

sqlparse==0.2.4 # used implicitly by Django Migrations engine when using RunSQL operation

希望有所帮助,我花了几个小时在网上浏览一些好的解决方案,但这部分由 Django 设计得非常糟糕(例如,真的错过了 Ruby on Rails 上提供的简洁易用的设计)。

于 2019-02-11T18:33:07.597 回答
3

对于未来的需要,这是我发现的最好方法:

https://github.com/GoodCloud/django-longer-username

于 2013-10-10T23:52:03.720 回答
1

auth.userAFAIK,如果你想要的话,你需要子类化。一个更简单且不那么冒险的解决方案可能是实现具有更长username字段的用户配置文件模型。为了避免冗余,您可以username使用随机生成的数字填充实际字段并退出使用它。

于 2011-01-14T19:11:05.727 回答