在迁移到Django 1.6时摆脱get_profile()

时间:2013-12-16 14:30:27

标签: python django deprecated user-profile

随着Django 1.5和自定义用户模型的引入,AUTH_PROFILE_MODULE被弃用。在我现有的Django应用程序中,我使用User模型,我还有Profile模型,其中包含User的外键,并在配置文件中存储有关用户的其他内容。目前正在使用AUTH_PROFILE_MODULE,并将其设置为“app.profile” 显然,我的代码往往需要做很多user.get_profile(),现在需要消失。

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

有没有办法 - 并且没有模型迁移 - 并且只能通过在某处创建/覆盖get_profile()函数my_user.userprofile_set.all()[0]这个函数?

那些走过这条道路,可以分享想法或经历的人吗?

如果我现在再次在哪里提供这项服务 - 显然不会这样做,但是对于一个半大型的现场制作系统我是开放的短片: - )

1 个答案:

答案 0 :(得分:67)

使用与内置User有关系的配置文件模型仍然是用于存储其他用户信息的完全合法的构造(在许多情况下推荐)。鉴于内置的Django 1对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()的{​​{1}}或profile的任何内容的简单搜索和替换(上述案例中的自动相关名称为related_name)。标准的django反向1-1语法实际上比user_profile更好!

将ForeignKey更改为OneToOneField

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

处理南迁移

如果您正在使用 South 进行迁移,那么上一部分中的代码更改可能会使South混淆为删除旧字段并在创建新字段时创建一个新字段{{1因此,您可能需要手动编辑迁移才能正确执行操作。一种方法是创建模式迁移,然后删除前向和后向方法,这样它实际上不会尝试做任何事情,但所以它仍然可以正常地冻结模型ForeignKey。然后,如果要完美地执行操作,还应将唯一约束添加到相应的数据库外键列。您可以使用SQL或南方手动执行此操作(通过手动编辑迁移方法,或在OneToOneField上设置schemamigration --auto并创建第一个南迁移,然后再将其切换为{{ 1}}并进行第二次迁移并清空前向/后向方法)。