我需要增加 auth 中的最大用户名大小以超过模型中定义的 30 个字符。怎么做到呢?我不确定只是自定义模型是正确或安全的方法。
4 回答
这里的答案是一个有趣的方法: Can django's auth_user.username be varchar(75)? 那怎么可能呢?
syncdb
一个覆盖 User 模型上的 max_length 属性的小应用程序,但请注意,如果未编辑表,则需要修改您的 DB 列
我个人使用修剪后的哈希作为我的用户名,如果发生极不可能的碰撞,它会通知我,主题为“你刚刚中了彩票!”
我在我们现有的基础设施中遇到了这种需求。
我们的整个后端都依赖于 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_username
和reverse_func_username
of是可选的RunPython
,取决于你愿意做什么。
请注意,RunSQL
需要sqlparse
依赖项,因此不要忘记将其添加到您的requirements.txt
文件中。
sqlparse==0.2.4 # used implicitly by Django Migrations engine when using RunSQL operation
希望有所帮助,我花了几个小时在网上浏览一些好的解决方案,但这部分由 Django 设计得非常糟糕(例如,真的错过了 Ruby on Rails 上提供的简洁易用的设计)。
对于未来的需要,这是我发现的最好方法:
auth.user
AFAIK,如果你想要的话,你需要子类化。一个更简单且不那么冒险的解决方案可能是实现具有更长username
字段的用户配置文件模型。为了避免冗余,您可以username
使用随机生成的数字填充实际字段并退出使用它。