【问题标题】:Get rid of get_profile() in a migration to Django 1.6在迁移到 Django 1.6 时摆脱 get_profile()
【发布时间】:2014-01-03 23:38:34
【问题描述】:

随着 Django 1.5 和自定义用户模型的引入,AUTH_PROFILE_MODULE 已被弃用。在我现有的 Django 应用程序中,我使用了 User 模型,并且我还有一个带有 User 外键的 Profile 模型,并将有关用户的其他内容存储在配置文件中。当前使用AUTH_PROFILE_MODULE,并设置为“app.profile”。
所以很明显,我的代码往往会做很多user.get_profile(),现在需要去掉。

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

有什么方法 - 并且没有模型迁移 - 并且只能通过在某处创建/覆盖 get_profile() 函数与 my_user.userprofile_set.all()[0]) 之类的东西?

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

如果我现在在哪里再做这项服务 - 显然不会走这条路,但有了一个半大型现场制作系统,我可以走捷径:-)

【问题讨论】:

  • 这些是我最终完成的步骤; (i) 创建了一个 utils 方法:返回 user.profile_set.all()[0] (ii) 在我在模型中使用外键引用 User 的所有位置添加 - 还添加了一个属性 user_profile(self),它返回上面 self (iii) 上的 utils 方法最后添加了当前用户配置文件并使其在请求上下文下可用(允许我用 user_profile 替换 user.get_profile 模板中的所有用法(我已添加)。然后进行大量搜索和替换.get_profile 在代码中 - 但现在似乎可以工作。不是最漂亮的东西,但可以工作。
  • 我想遵循这种方法,但我不太明白。您在哪里添加属性user_profile?您如何使其在请求上下文中可用?

标签: python django deprecated user-profile


【解决方案1】:

使用与内置 User 相关的配置文件模型仍然是存储其他用户信息的完全合法结构(在许多情况下建议使用)。鉴于内置的 Django 1-to-1 语法在这里干净优雅地工作,现在已弃用的 AUTH_PROFILE_MODULEget_profile() 东西最终变得不必要了。

如果您已经在您的个人资料模型上使用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。它最终是对get_profile() 的简单搜索和替换profile 或您的related_name 是什么(在上述情况下,自动相关名称为user_profile)。标准的 django reverse 1-1 语法实际上比get_profile() 更好!

将 ForeignKey 更改为 OneToOneField

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

应对南迁

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

【讨论】:

  • 非常简洁的答案。明天,您将在 23 小时内赢得赏金 :)
  • 帮了大忙。谢谢本。
猜你喜欢
  • 2019-05-23
  • 2018-04-13
  • 2017-04-20
  • 1970-01-01
  • 2015-02-13
  • 2011-01-23
  • 2011-04-05
  • 1970-01-01
  • 2019-02-10
相关资源
最近更新 更多