Расширение 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
в случае необходимости отката, как описано здесь.