简体   繁体   English

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

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

I have a model with a foreign key that references the username field of auth.User . 我有一个带有外键的模型,它引用了auth.User用户 名字段 The original field has a maximum length of 150. But Django generates a foreign key with a maximum length of 30. 原始字段的最大长度为150.但Django生成一个最大长度为30的外键。

In my app's models.py: 在我的应用程序的models.py中:

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

In django.contrib.auth.models: 在django.contrib.auth.models中:

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

Generated SQL: 生成的SQL:

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

This only happens when referencing auth.User.username. 这仅在引用auth.User.username时发生。 If I reference a long field in my own model, the foreign key is generated fine. 如果我在自己的模型中引用一个长字段,则生成外键。

Why is that? 这是为什么? How can I overcome it? 我怎么能克服它?

Using Django 1.11.4 and Python 3.6.2. 使用Django 1.11.4和Python 3.6.2。 I tried PostgreSQL and SQLite and the problem occurs on both. 我尝试了PostgreSQL和SQLite,两者都出现了问题。

CLARIFICATION: From the answers so far I think my question was misunderstood. 澄清:从答案到目前为止,我认为我的问题被误解了。 I am not looking for a way to have long usernames. 我不是在寻找一种拥有长用户名的方法。 My problem is that the stock User model that comes with Django has one max_length (150), but when your model refers to it, the foreign hey has a shorter max_length of 30. Therefore if a user is registered with a username of 31 characters, I will not be able to create child objects of that user, because the foreign key constraint will be violated. 我的问题是Django附带的股票用户模型有一个max_length(150),但是当你的模型引用它时,外来的hey有一个更短的max_length为30.因此,如果用户注册了31个字符的用户名,我将无法创建该用户的子对象,因为将违反外键约束。 And I need this because I have a REST API whose URLs nest resources under uses, that are referred by username, not ID. 我需要这个,因为我有一个REST API,其URL嵌套使用的资源,由用户名而不是ID引用。 For example: /users/<username>/profiles/... 例如: /users/<username>/profiles/...

UPDATE: I think the reason for this behavior is the undocumented swappable property of the User model. 更新:我认为这种行为的原因是User模型的未记录的可交换属性。 It is designed to be replaceable by custom models. 它可以通过自定义模型进行更换。 However, the configured model must have its data in the initial migration of the app that defines the model. 但是,配置的模型必须在定义模型的应用程序的初始迁移中具有其数据。 The migrations code seems to generate references to the initial migration of swappable models. 迁移代码似乎生成对可交换模型的初始迁移的引用。 I am using the default User model, and its initial migration sets the username to 30 chars. 我使用默认的用户模型,其初始迁移将用户名设置为30个字符。 Hence my username FKs are 30 chars long. 因此我的用户名FKs长30个字符。 I am able to work around this with a RunSQL migration to alter the FK data type to varchar(15), but I am in doubt if it's the right thing to do. 我能够通过RunSQL迁移来解决这个问题,将FK数据类型改为varchar(15),但我怀疑这是否正确。

Is recommended use short identifier, varchar(30) is a long number, something like 999999999999999999999999999999, when Django make identifiers always use the same number. 建议使用短标识符,varchar(30)是一个长数字,类似于999999999999999999999999999999,当Django使标识符始终使用相同的数字时。 I don't think that you are going to use so much users if you reach that number you should create another type of identifier. 如果你达到这个数字,我不认为你会使用这么多用户你应该创建另一种类型的标识符。 Remember the long of the user_id field is the id of the username and not the string 请记住,user_id字段的长度是用户名的id而不是字符串

You can use this hack described in this SO answer , but be very careful!. 你可以使用这个SO答案中描述的这个hack,但要非常小心!

Or you can use this package . 或者你可以使用这个包

However, I think that, as described in this discussion , the best way would be to create a custom User model and do whatever you want there. 但是,我认为,正如本讨论中所述,最好的方法是创建自定义User模型并在那里做任何你想做的事情。

Hope it helps! 希望能帮助到你!

You must use custom user model.Taken from django docs. 您必须使用自定义用户模型。来自django docs。

150 characters or fewer. 150个字符或更少。 Usernames may contain alphanumeric, _, @, +, . 用户名可以包含字母数字,_,@,+ ,. and - characters. 和 - 字符。

The max_length should be sufficient for many use cases. 对于许多用例,max_length应该足够了。 If you need a longer length, please use a custom user model. 如果您需要更长的长度,请使用自定义用户模型。 If you use MySQL with the utf8mb4 encoding (recommended for proper Unicode support), specify at most max_length=191 because MySQL can only create unique indexes with 191 characters in that case by default. 如果您使用带有utf8mb4编码的MySQL(建议用于正确的Unicode支持),请最多指定max_length = 191,因为默认情况下,MySQL只能创建包含191个字符的唯一索引。

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

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