繁体   English   中英

为什么Django为auth.User.username设置了较短的外键最大长度?

[英]Why does Django set a shorter maximum length of foreign keys to auth.User.username?

我有一个带有外键的模型,它引用了auth.User用户 名字段 原始字段的最大长度为150.但Django生成一个最大长度为30的外键。

在我的应用程序的models.py中:

class Profile(models.Model):
    user = models.ForeignKey('auth.User', to_field='username')

在django.contrib.auth.models中:

username = models.CharField(
    _('username'),
    max_length=150,

生成的SQL:

CREATE TABLE "myapp_profile" (
    "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
    "user_id" varchar(30) NOT NULL REFERENCES "auth_user" ("username")
);

这仅在引用auth.User.username时发生。 如果我在自己的模型中引用一个长字段,则生成外键。

这是为什么? 我怎么能克服它?

使用Django 1.11.4和Python 3.6.2。 我尝试了PostgreSQL和SQLite,两者都出现了问题。

澄清:从答案到目前为止,我认为我的问题被误解了。 我不是在寻找一种拥有长用户名的方法。 我的问题是Django附带的股票用户模型有一个max_length(150),但是当你的模型引用它时,外来的hey有一个更短的max_length为30.因此,如果用户注册了31个字符的用户名,我将无法创建该用户的子对象,因为将违反外键约束。 我需要这个,因为我有一个REST API,其URL嵌套使用的资源,由用户名而不是ID引用。 例如: /users/<username>/profiles/...

更新:我认为这种行为的原因是User模型的未记录的可交换属性。 它可以通过自定义模型进行更换。 但是,配置的模型必须在定义模型的应用程序的初始迁移中具有其数据。 迁移代码似乎生成对可交换模型的初始迁移的引用。 我使用默认的用户模型,其初始迁移将用户名设置为30个字符。 因此我的用户名FKs长30个字符。 我能够通过RunSQL迁移来解决这个问题,将FK数据类型改为varchar(15),但我怀疑这是否正确。

建议使用短标识符,varchar(30)是一个长数字,类似于999999999999999999999999999999,当Django使标识符始终使用相同的数字时。 如果你达到这个数字,我不认为你会使用这么多用户你应该创建另一种类型的标识符。 请记住,user_id字段的长度是用户名的id而不是字符串

你可以使用这个SO答案中描述的这个hack,但要非常小心!

或者你可以使用这个包

但是,我认为,正如本讨论中所述,最好的方法是创建自定义User模型并在那里做任何你想做的事情。

希望能帮助到你!

您必须使用自定义用户模型。来自django docs。

150个字符或更少。 用户名可以包含字母数字,_,@,+ ,. 和 - 字符。

对于许多用例,max_length应该足够了。 如果您需要更长的长度,请使用自定义用户模型。 如果您使用带有utf8mb4编码的MySQL(建议用于正确的Unicode支持),请最多指定max_length = 191,因为默认情况下,MySQL只能创建包含191个字符的唯一索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM