Расширение Django приложением сайтов для предоставления текущего рабочего приложения в качестве SAAS

У меня есть работающее развернутое приложение Django в производстве, с некоторыми пользователями и различными объектами, хранящимися в базе данных. Клиент сказал мне, можно ли реплицировать веб-сайт, изменив некоторые мелочи, такие как шаблоны, логотипы и т. Д., Но поддерживая некоторых пользователей и объекты.

Я слышал о 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)

Для других классов, поскольку я не переопределил менеджер по умолчанию, я просто переопределил objects:

objects = CurrentSiteManager()

Все работало нормально, пока я не попытался проверить свое текущее работающее приложение. Поскольку объекты в базе данных не имеют связанного сайта (User.sites queryset пуст) Я не могу войти ни с каким пользователем.

Таким образом, я вернулся, отменил миграцию (которая учитывает изменение менеджеров), и теперь я нахожусь в исходном состоянии перед любой модификацией сайта.

Я пытался найти документацию о том, как подойти к этому, но я еще не нашел учебник или некоторые хорошие практики, как выполнить эту "начальную" миграцию данных для сайтов, когда в БД уже есть данные.

Я предполагаю, что мне нужно выполнить миграцию сайтов, затем назначить текущий (и единственный) рабочий сайт всем данным (пользователям и связанным объектам), затем сменить менеджеров и запустить миграцию менеджеров. Это оно? Или я что-то упустил?

Любая помощь или понимание будут очень признательны.

1 ответ

Решение

Если я правильно понимаю, похоже, проблема в том, что с вашим изменением пользователь теперь ДОЛЖЕН быть привязан хотя бы к одному сайту, чтобы иметь возможность войти в систему. Поскольку ваши текущие пользователи не связаны ни с какими сайтами, это создает проблему входа в систему.

Если это так, я бы предложил добавить миграцию данных после миграций схемы в вашей ветви. Эта миграция данных будет проходить через всех пользователей и добавлять settings.SITE_ID в user.sites, Вы также захотите создать функцию, которая делает противоположное, удаляет запись из user.sites в случае необходимости отката, как описано здесь.

Другие вопросы по тегам