pypi django-tenants 3.13.0
v3.13.0

2 hours ago

Fixes

Cloning a schema owned by a role whose name needs quoting (#1239, fixes #1189). Role names were interpolated into generated DDL raw, so a role containing a hyphen — or starting with a digit — made the statement a syntax error and the clone failed outright:

CREATE SCHEMA new_tenant AUTHORIZATION my-role
                                        ^ syntax error at or near "-"

Three places were affected: CREATE SCHEMA ... AUTHORIZATION, ALTER SEQUENCE ... OWNER TO, and the ALTER TABLE ... OWNER TO in pg_get_tabledef. Table and type owners were already quoted at their SELECT and are unchanged. This also resolves the long-standing #561, which was the same bug seen through a role name beginning with a digit.

STORAGES in the test project and examples (#1240, fixes #1095, #1173). DEFAULT_FILE_STORAGE and STATICFILES_STORAGE were deprecated in Django 4.2 and removed in 5.1, where they are silently ignored — but the test project and all three example tutorials still set them. Anyone who copied an example was quietly getting single-tenant file storage:

STORAGES['default'] STORAGES['staticfiles']
before FileSystemStorage StaticFilesStorage
after TenantFileSystemStorage TenantStaticFilesStorage

Nothing errored, which is why it went unnoticed. docs/files.rst now leads with STORAGES, keeping DEFAULT_FILE_STORAGE documented for Django < 4.2, which is still supported.

New

get_current_tenant() (#1241, closes #1217). get_tenant() takes a request, so there was no way to ask which tenant am I in from a helper function, a Celery task, or a signal handler:

from django_tenants.utils import get_current_tenant

def send_welcome_email(user):
    tenant = get_current_tenant()   # no request needed

tenant_context() sets the real instance, so that is what comes back. schema_context() only ever knows a schema name, so a FakeTenant is returned there — read its schema_name, or use tenant_context() when you need the model.

Breaking

migrate_schemas no longer accepts --list / -l (#794). Nothing ever read the flag — Django moved that functionality to showmigrations long ago — so it silently did nothing. Passing it now raises unrecognized arguments rather than being accepted and ignored. Use showmigrations, or tenant_command showmigrations --schema=<name> for a single tenant.

Also

  • is_public_schema's unused app argument is now optional, so both {% is_public_schema %} and {% is_public_schema app %} work (#339).
  • Regression test added for cloning inside transaction.atomic() — fixed in 3.12.0 by #1150 but shipped without a test, so nothing prevented transaction.commit() returning (#1155, #694).

Housekeeping

The issue tracker has had a thorough pass: 254 open issues down to 88. Everything closed carries a reason, and anything closed as stale can be reopened — if one of them is still biting you on 3.13.0, please do, ideally with the versions and steps to reproduce.

The missing v3.8.0 (#1156) and v3.10.1 (#1222) tags have also been created, pointing at the commits those releases were built from.

Full Changelog: v3.12.0...v3.13.0

Don't miss a new django-tenants release

NewReleases is sending notifications on new releases.