随着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]
这个函数?
那些走过这条道路,可以分享想法或经历的人吗?
如果我现在再次在哪里提供这项服务 - 显然不会这样做,但是对于一个半大型的现场制作系统我是开放的短片: - )
答案 0 :(得分:67)
使用与内置User
有关系的配置文件模型仍然是用于存储其他用户信息的完全合法的构造(在许多情况下推荐)。鉴于内置的Django 1对1语法在这里干净而优雅地工作,现在已弃用的AUTH_PROFILE_MODULE
和get_profile()
内容最终变得不必要了。
如果您已经在个人资料模型上使用OneToOneField
到User
,那么从旧用法的过渡实际上很容易,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
更好!
但是,我意识到这并不能完全回答你的问题。您表明您在个人资料模块中使用了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}}并进行第二次迁移并清空前向/后向方法)。