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

Jen*_*rom 25 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]

那些走在这条道路上并可以分享想法或经历的人?

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

Ben*_*rts 67

使用与内置关系相关的配置文件模型User仍然是用于存储其他用户信息的完全合法的构造(并且在许多情况下推荐).该AUTH_PROFILE_MODULEget_profile()那个现在已经过时,刚刚结束了不必要的东西,因为内置Django的1对1的语法作品干净,优雅在这里.

如果您已经在配置文件模型上使用了OneToOneFieldto User,那么从旧用法的转换实际上很容易,这就是在不推荐使用get_profile之前建议设置配置文件模块的方式.

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  
Run Code Online (Sandbox Code Playgroud)

如果你不熟悉使这成为可能的句法魔法,请看这里OneToOneField.它最终是一个简单的搜索和替换get_profile()profile或任何你related_name的(在上述情况下自动相关的名称将是user_profile).标准的django反向1-1语法实际上比get_profile()!

将ForeignKey更改为OneToOneField

但是,我意识到这并不能完全回答你的问题.您表明您使用ForeignKeyUser您的个人资料模块中,而不是一个OneToOne,这是很好的,但如果你把它作为一个语法不那么简单ForeignKey,因为你在你的跟进评论请注意.
假设你ForeignKey在实践中使用你的实际作为一个唯一的外键(基本上是一对一),因为在数据库中a OneToOneField只是一个ForeignKeyunique=True约束的字段,你应该能够在你的代码中将ForeignKey字段更改为aOneToOneField实际上必须进行重要的数据库迁移或导致任何数据丢失.

处理南迁移

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