迁移到Django 1.6时去掉Get_profile()

2024-05-23 15:26:14 发布

您现在位置:Python中文网/ 问答频道 /正文

随着Django 1.5和自定义用户模型的引入,AUTH_PROFILE_MODULE变得不受欢迎。在我现有的Django应用程序中,我使用User模型,并且我还有一个Profile模型,该模型带有User的外键,并且在概要文件中存储有关用户的其他信息。当前正在使用AUTH_PROFILE_MODULE,并且设置为“app.profile”。
所以很明显,我的代码倾向于做大量的工作,现在这需要消失。

现在,我可以创建一个新的自定义用户模型(只需要扩展我的配置文件模型User),但是在所有其他地方,我现在有一个用户的外键也需要更改。。。所以在我的现场服务中,这将是一次大规模的迁移。

有没有任何方法-而且没有模型迁移-并且只有通过在某处创建/重写get_profile()函数(比如my_user.userprofile_set.all()[0])?

有没有人走上这条路,可以分享想法或经验?

如果我现在在哪里再做这项服务-显然不会走这条路,但与一个半大型的现场生产系统,我是开放的捷径:-)


Tags: 文件django用户模型auth信息app应用程序
1条回答
网友
1楼 · 发布于 2024-05-23 15:26:14

使用与内置User相关的配置文件模型仍然是存储附加用户信息的完全合法的构造(在许多情况下建议使用)。现在被弃用的AUTH_PROFILE_MODULEget_profile()这些东西最终变得不必要了,因为内置的Django 1对1语法在这里工作得干净优雅。

如果您已经在概要模型上使用OneToOneFieldUser,那么从旧用法的转换实际上很容易,这就是the profile module was recommended to be set up before get_profile was deprecated

class UserProfile(models.Model):
    user = OneToOneField(User, related_name="profile")
    # add profile fields here, e.g.,
    nickname = CharField(...)

# usage: no get_profile() needed. Just standard 1-to-1 reverse syntax!
nickname = request.user.profile.nickname  

如果您不熟悉使这成为可能的OneToOneField的语法魔力,请参见here。它最终是对profile或任何related_nameget_profile()的简单搜索和替换(在上述情况下,自动相关的名称将是user_profile)。标准的django reverse 1-1语法实际上比get_profile()更好!

将外键更改为OneToOneField

不过,我知道这并不能完全回答你的问题。您表示您在概要文件模块中使用了ForeignKeyUser,而不是OneToOne,这很好,但是如果您将其保留为ForeignKey,语法就不会那么简单了,正如您在后续评论中所注意到的那样 假设您在实践中将ForeignKey用作唯一外键(本质上是1对1),考虑到in the DB a ^{} is just a ^{} field with a ^{} constraint,您应该能够在代码中将ForeignKey字段更改为OneToOneField,而不必实际进行数据库迁移或导致任何数据丢失。

处理南迁问题

如果您使用South进行迁移,那么如果您执行了一个schemamigration --auto,上一节中的代码更改可能会将South混淆为删除旧字段并创建一个新字段,因此您可能需要手动编辑迁移以正确执行操作。一种方法是创建schemamigration,然后清空forward和backward方法,这样它实际上就不会尝试做任何事情,但是它仍然会在向前移动时正确冻结模型。然后,如果您想做得很好,还应该将unique约束添加到相应的数据库外键列中。您可以使用SQL手动执行此操作,也可以通过South(通过手动编辑迁移方法,或者在ForeignKey上设置unique=True,并在切换到OneToOneField前创建第一个South迁移,然后执行第二次迁移并清空forwards/backwards方法)。

相关问题 更多 >