2017-08-09 25 views
0

我在生产环境中部署了一个Django应用程序,其中一些用户和各种对象存储在数据库中。客户告诉我,网站是否可以复制,改变一些小的东西,比如模板,徽标等,但保留一些用户和对象。使用网站应用程序扩展Django以提供当前可运行的应用程序SAAS

很久以前我听说过django.contrib.sites,所以在阅读完描述之后,它似乎是最佳选择。我直接去了,把django.contrib.sites加到INSTALLED_APPS,把SITE_ID放在我的settings.py里,然后执行迁移。

我选择要使用的网站一ManyToManyField,因为用户可能会登录在一个或多个站点:

sites = models.ManyToManyField(Site) 

既然我已经修改了管理者对于某些型号,如User,我不得不重写我的自定义get_queryset,只返回当前站点的用户,所以我增加了filter(sites=settings.SITE_ID)到返回的查询集,因为我的文档中看到:

from django.contrib.auth.models import BaseUserManager 

class UserManager(BaseUserManager): 

    def get_queryset(self): 
     return super(UserManager, self).get_queryset().filter(
      is_active=True).filter(sites=settings.SITE_ID) 

对于其它类,因为我没有Ø verride默认的经理,我只是做了覆盖objects

objects = CurrentSiteManager() 

一切工作正常,直到我试图测试我当前工作的应用程序。由于数据库中的对象没有关联的站点(User.sites查询集为空),我无法用任何用户登录。

因此,我回去了,恢复了迁移(考虑到管理者的修改),现在我处于初始状态,在任何网站修改之前。

我一直在试图找到关于如何解决这个问题的文档,但是我还没有找到关于如何在数据库中已有数据的情况下对网站执行此“初始”数据迁移的教程或一些良好实践。

我的猜测是我必须执行网站迁移,然后将当前(且唯​​一)工作站点分配给所有数据(用户和相关对象),然后更改管理器并运行管理器迁移。是吗?或者我错过了什么?

任何帮助或见解将不胜感激。

回答

1

如果我的理解正确,听起来像问题在于,随着您的更改,用户现在必须绑定到至少一个网站才能登录。由于您当前的用户未与任何网站关联,因此会造成登录问题。

如果是这种情况,我建议在分支架构迁移后添加一个data migration。此数据迁移将遍历所有用户,并将settings.SITE_ID添加到user.sites。如果需要回滚,您还需要创建一个相反的功能,从user.sites中删除条目,如here所述。

+0

不错,非常感谢。这就是我所做的,它的工作。只是一个简单的问题:是否真的强制实施回滚?我的猜测是,如果我需要返回,由于模型迁移将删除Site模型,引用将消失,因此删除的对象,我是对吗? – vabada

+0

嗯,我不是很积极,但它可能实际上创建一个外键错误,当您尝试删除时,因为您试图删除数据库中的对象引用的模型。更重要的是,恕我直言,为所有数据迁移创建回滚只是一种好的做法。 – MrName

+0

无论如何,我绝对同意这种良好的做法。谢谢你的提示! – vabada

相关问题