在向Django 1.6的迁移中摆脱get_profile()

发布于 2021-01-29 18:00:18

随着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
被浏览
38
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    使用与内置关系相关的配置文件模型User仍然是用于存储其他用户信息的完全合法的构造(在许多情况下建议使用)。鉴于内置的Django
    1-to-1语法在此处干净利落地工作,因此现在不再使用的AUTH_PROFILE_MODULEget_profile()东西变得不必要了。

    如果您已经 在概要文件模型上
    使用OneToOneFieldUser则从旧用法的转换实际上很容易,这是建议在不赞成使用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
    

    如果您不熟悉的语法,请参见此处OneToOneField,这使这成为可能。最终可以轻松搜索并替换get_profile()forprofile或无论您related_name是什么(在上述情况下,与汽车相关的名称都将是user_profile)。标准的Django反向1-1语法实际上比get_profile()

    将ForeignKey更改为OneToOneField

    但是,我意识到这并不能完全回答您的问题。您表示您在个人资料模块中使用了ForeignKeyto
    User,而不是使用OneToOne,这很好,但是如果您将其保留为ForeignKey,语法就不会那么简单,就像您在后续评论中所指出的那样。
    假设您ForeignKey在实践中将自己用作唯一的外键(本质上是一对一),因为在数据库中aOneToOneField只是一个ForeignKey带有unique=True约束的字段,您应该能够在代码中
    将该ForeignKey字段更改为aOneToOneField而不用实际上必须进行大量的数据库迁移或导致任何数据丢失。

    应对南方移民

    如果您使用 South
    进行迁移,则执行上一节中的代码更改可能会使South误删除旧字段并创建新字段(如果您执行)schemamigration --auto,因此您可能需要手动编辑迁移才能正确执行操作。一种方法是先创建schemamigration,然后取消前进和后退方法,这样它实际上就不会尝试做任何事情,但是仍然可以继续冻结模​​型OneToOneField。然后,如果您想做得完美,则还应该将唯一约束添加到相应的数据库外键列中。您既可以使用SQL手动执行此操作,也可以通过South(通过手动编辑迁移方法或通过unique=TrueForeignKey并在将其切换为之前创建第一个South迁移,然后OneToOneField进行第二个迁移,并取消掉前进/后退方法。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看