Django Tenants не переключается между тенантами (схемами)
Использую библиотеку django-tenants для проекта.
Для каждого нового зарегистрирована пользователя создается тенант с новой схемой. Я хочу реализовать логику, чтобы доступ к тенантам осуществлялся через project-url.ru/user/<username>/...
без использования субдоменов.
Однако при заходе в приложение тенанта, Django не меняет тенант/схему на пользовательскую, а остается в public.
Прошу помочь разобраться почему Django не переключается между тенантами/схемами.
setting.py
TENANT_MODEL = 'users.Tenant'
TENANT_DOMAIN_MODEL = 'users.Domain'
PUBLIC_SCHEMA_URLCONF = 'users.users-urls'
TENANT_SUBFOLDER_PREFIX = '/user'
DATABASE_ROUTERS = (
'django_tenants.routers.TenantSyncRouter',
)
MIDDLEWARE = [
'django_tenants.middleware.TenantSubfolderMiddleware',
...
]
Новый тенант создается в момент регистрации пользователя. Вот логика созданию тенанта
def create_user_tenant(request):
"""
Создание нового тенанта в момент регистрации нового пользователя
"""
user = UserClass.objects.get(username=request.POST['username'])
schema_name = f'{user.username}_schema'
try:
with transaction.atomic():
tenant = Tenant(schema_name=schema_name, user=user)
tenant.save()
logger.debug(f'Tenant {tenant} created')
except IntegrityError as e:
logger.error(f'Error creating tenant or domain for user {user.username}: {e}')
except Exception as e:
logger.error(f'Unexpected error creating tenant or domain for user {user.username}: {e}')
Новая схема в базе с корректным именем создается. Проверил. Вот как заданы urls:
users-url.py
urlpatterns = [
path('<str:username>/products/', include('products.products-urls', namespace='products')),
path('<str:username>/storage/', include('storage.storage-urls', namespace='storage')),
...
]
products-urls.py
urlpatterns = [
...
path('items-list/', items_list, name='items-list'),
...
]
Логика авторизации:
def login(request):
"""
Метод авторизации пользователя
"""
error_msg = ''
if request.POST:
logger.debug(f"Login request")
form = UserLoginForm(data=request.POST)
if form.is_valid():
username = request.POST['username']
password = request.POST['password']
user = auth.authenticate(username=username, password=password)
if user:
logger.debug(f"User {username} authenticated")
auth.login(request, user)
return redirect(f'/{username}/products/items-list/')
И метод, куда переходим после успешной авторизации
@transaction.atomic
def items_list(request, username):
logger.debug(f'Current connected schema: {connection.schema_name}')
context = {
'username': UserClass.objects.get(username=username),
'items_list': ItemsClass.objects.order_by('name'),
}
return render(request, 'products/items/items_list.html', context)
И вот тут на странице получается резонная ошибка, потому что соответствующих полей в схеме public нет. Они есть только в пользовательском тенанте (это тоже проверил)
ProgrammingError at /aaa/products/items-list/
relation "products_itemsclass" does not exist
LINE 1: ...fats", "products_itemsclass"."carbohydrates" FROM "products_...
А в логе вижу
2024-08-19 12:18:23,979 - DEBUG (item_view.items_list): Current connected schema: public
А должно быть aaa_schema
. Очень прошу помочь.
Делал по документации: https://django-tenants.readthedocs.io/en/latest/install.html#sub-folder-support