0

我在生产中有一个工作部署的 Django 应用程序,一些用户和各种对象存储在数据库中。客户告诉我是否可以复制网站,更改一些小东西,例如模板、徽标等,但保留一些用户和对象。

django.contrib.sites很早以前就听说过,所以在阅读了描述之后,它似乎是完美的选择。我直接动手,添加django.contrib.sitesINSTALLED_APPS,放入SITE_ID我的settings.py,并执行迁移。

我选择对ManyToManyField站点使用 a,因为用户可能能够登录一个或多个站点:

sites = models.ManyToManyField(Site)

由于我已经修改了某些模型的管理器,例如User,我不得不覆盖我的 custom 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)

对于其他类,由于我没有覆盖默认管理器,我只是覆盖了objects

objects = CurrentSiteManager()

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

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

我一直在尝试查找有关如何解决此问题的文档,但是我还没有找到有关如何在数据库中已有数据时为站点执行此“初始”数据迁移的教程或一些良好实践。

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

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

4

1 回答 1

1

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

如果是这种情况,我建议在您的分支中的架构迁移之后添加数据迁移。此数据迁移将遍历所有用户并添加settings.SITE_IDuser.sites. 您还需要创建一个执行相反操作的函数,user.sites在需要回滚的情况下删除条目,如此所述。

于 2017-08-09T17:00:22.723 回答