0001-multitenant-remove-django-1.8-compatibility-code-fro.patch
hobo/multitenant/management/commands/__init__.py | ||
---|---|---|
36 | 36 |
else: |
37 | 37 |
cmdclass = load_command_class(app_name, obj.COMMAND_NAME) |
38 | 38 | |
39 |
if django.VERSION < (1, 8, 0): |
|
40 |
# inherit the options from the original command |
|
41 |
obj.option_list = cmdclass.option_list |
|
42 |
obj.option_list += ( |
|
43 |
make_option("-d", "--domain", dest="domain"), |
|
44 |
) |
|
45 |
obj.option_list += ( |
|
46 |
make_option("-p", "--skip-public", dest="skip_public", action="store_true", default=False), |
|
47 |
) |
|
48 | ||
49 | 39 |
# prepend the command's original help with the info about schemata iteration |
50 | 40 |
obj.help = "Calls %s for all registered schemata. You can use regular %s options. "\ |
51 | 41 |
"Original help for %s: %s" % (obj.COMMAND_NAME, obj.COMMAND_NAME, obj.COMMAND_NAME, |
... | ... | |
86 | 76 | |
87 | 77 | |
88 | 78 |
class InteractiveTenantOption(object): |
89 |
def __init__(self, *args, **kwargs): |
|
90 |
super(InteractiveTenantOption, self).__init__(*args, **kwargs) |
|
91 |
if django.VERSION < (1, 8, 0): |
|
92 |
self.option_list += ( |
|
93 |
make_option("-d", "--domain", dest="domain", help="specify tenant domain"), |
|
94 |
) |
|
95 | ||
96 | 79 |
def add_arguments(self, parser): |
97 | 80 |
parser.add_argument("-d", "--domain", dest="domain", help='specify tenant domain') |
98 | 81 | |
... | ... | |
136 | 119 |
def __new__(cls, *args, **kwargs): |
137 | 120 |
obj = super(TenantWrappedCommand, cls).__new__(cls, *args, **kwargs) |
138 | 121 |
obj.command_instance = obj.COMMAND() |
139 |
obj.option_list = obj.command_instance.option_list |
|
140 | 122 |
return obj |
141 | 123 | |
142 | 124 |
def add_arguments(self, parser): |
... | ... | |
151 | 133 | |
152 | 134 | |
153 | 135 |
class SyncCommon(BaseCommand): |
154 |
if django.VERSION < (1, 8, 0): |
|
155 |
option_list = ( |
|
156 |
make_option('--tenant', action='store_true', dest='tenant', default=False, |
|
157 |
help='Tells Django to populate only tenant applications.'), |
|
158 |
make_option('--shared', action='store_true', dest='shared', default=False, |
|
159 |
help='Tells Django to populate only shared applications.'), |
|
160 |
make_option('--app_label', action='store', dest='app_label', nargs='?', |
|
161 |
help='App label of an application to synchronize the state.'), |
|
162 |
make_option('--migration_name', action='store', dest='migration_name', nargs='?', |
|
163 |
help=('Database state will be brought to the state after that ' |
|
164 |
'migration. Use the name "zero" to unapply all migrations.')), |
|
165 |
make_option("-d", "--domain", dest="domain"), |
|
166 |
) |
|
167 | ||
168 | 136 |
def __init__(self, stdout=None, stderr=None, no_color=False): |
169 | 137 |
if django.VERSION >= (1, 8, 0): |
170 | 138 |
super(SyncCommon, self).__init__(stdout, stderr, no_color) |
... | ... | |
172 | 140 |
super(SyncCommon, self).__init__() |
173 | 141 | |
174 | 142 |
def add_arguments(self, parser): |
175 |
# for django 1.8 and above |
|
176 | 143 |
parser.add_argument('--tenant', action='store_true', dest='tenant', default=False, |
177 | 144 |
help='Tells Django to populate only tenant applications.') |
178 | 145 |
parser.add_argument('--shared', action='store_true', dest='shared', default=False, |
hobo/multitenant/management/commands/legacy/migrate_schemas.py | ||
---|---|---|
1 |
# this file derive from django-tenant-schemas |
|
2 |
# Author: Bernardo Pires Carneiro |
|
3 |
# Email: carneiro.be@gmail.com |
|
4 |
# License: MIT license |
|
5 |
# Home-page: http://github.com/bcarneiro/django-tenant-schemas |
|
6 |
from django.conf import settings |
|
7 |
from django.db import connection |
|
8 |
from south import migration |
|
9 |
from south.migration.base import Migrations |
|
10 |
from south.management.commands.migrate import Command as MigrateCommand |
|
11 |
from hobo.multitenant.middleware import TenantMiddleware |
|
12 |
from hobo.multitenant.management.commands import SyncCommon |
|
13 | ||
14 | ||
15 |
class Command(SyncCommon): |
|
16 |
help = "Migrate schemas with South" |
|
17 |
option_list = MigrateCommand.option_list + SyncCommon.option_list |
|
18 | ||
19 |
def handle(self, *args, **options): |
|
20 |
super(Command, self).handle(*args, **options) |
|
21 | ||
22 |
if self.sync_public: |
|
23 |
self.migrate_public_apps() |
|
24 |
if self.sync_tenant: |
|
25 |
self.migrate_tenant_apps(self.domain) |
|
26 | ||
27 |
def _set_managed_apps(self, included_apps, excluded_apps): |
|
28 |
""" while sync_schemas works by setting which apps are managed, on south we set which apps should be ignored """ |
|
29 |
ignored_apps = [] |
|
30 |
if excluded_apps: |
|
31 |
for item in excluded_apps: |
|
32 |
if item not in included_apps: |
|
33 |
ignored_apps.append(item) |
|
34 | ||
35 |
for app in ignored_apps: |
|
36 |
app_label = app.split('.')[-1] |
|
37 |
settings.SOUTH_MIGRATION_MODULES[app_label] = 'ignore' |
|
38 | ||
39 |
def _save_south_settings(self): |
|
40 |
self._old_south_modules = None |
|
41 |
if hasattr(settings, "SOUTH_MIGRATION_MODULES") and settings.SOUTH_MIGRATION_MODULES is not None: |
|
42 |
self._old_south_modules = settings.SOUTH_MIGRATION_MODULES.copy() |
|
43 |
else: |
|
44 |
settings.SOUTH_MIGRATION_MODULES = dict() |
|
45 | ||
46 |
def _restore_south_settings(self): |
|
47 |
settings.SOUTH_MIGRATION_MODULES = self._old_south_modules |
|
48 | ||
49 |
def _clear_south_cache(self): |
|
50 |
for mig in list(migration.all_migrations()): |
|
51 |
delattr(mig._application, "migrations") |
|
52 |
Migrations._clear_cache() |
|
53 | ||
54 |
def _migrate_schema(self, tenant): |
|
55 |
connection.set_tenant(tenant, include_public=False) |
|
56 |
MigrateCommand().execute(*self.args, **self.options) |
|
57 | ||
58 |
def migrate_tenant_apps(self, schema_name=None): |
|
59 |
self._save_south_settings() |
|
60 | ||
61 |
apps = self.tenant_apps or self.installed_apps |
|
62 |
self._set_managed_apps(included_apps=apps, excluded_apps=self.shared_apps) |
|
63 | ||
64 |
if schema_name: |
|
65 |
self._notice("=== Running migrate for schema: %s" % schema_name) |
|
66 |
connection.set_schema_to_public() |
|
67 |
tenant = TenantMiddleware.get_tenant_by_hostname(schema_name) |
|
68 |
self._migrate_schema(tenant) |
|
69 |
else: |
|
70 |
all_tenants = TenantMiddleware.get_tenants() |
|
71 |
if not all_tenants: |
|
72 |
self._notice("No tenants found") |
|
73 | ||
74 |
for tenant in all_tenants: |
|
75 |
Migrations._dependencies_done = False # very important, the dependencies need to be purged from cache |
|
76 |
self._notice("=== Running migrate for schema %s" % tenant.schema_name) |
|
77 |
self._migrate_schema(tenant) |
|
78 | ||
79 |
self._restore_south_settings() |
|
80 | ||
81 |
def migrate_public_apps(self): |
|
82 |
self._save_south_settings() |
|
83 | ||
84 |
apps = self.shared_apps or self.installed_apps |
|
85 |
self._set_managed_apps(included_apps=apps, excluded_apps=self.tenant_apps) |
|
86 | ||
87 |
self._notice("=== Running migrate for schema public") |
|
88 |
MigrateCommand().execute(*self.args, **self.options) |
|
89 | ||
90 |
self._clear_south_cache() |
|
91 |
self._restore_south_settings() |
hobo/multitenant/management/commands/list_tenants.py | ||
---|---|---|
4 | 4 |
class Command(BaseCommand): |
5 | 5 |
requires_model_validation = True |
6 | 6 |
can_import_settings = True |
7 |
option_list = BaseCommand.option_list |
|
8 | 7 | |
9 | 8 |
def handle(self, **options): |
10 | 9 |
all_tenants = TenantMiddleware.get_tenants() |
hobo/multitenant/management/commands/migrate_schemas.py | ||
---|---|---|
1 | 1 |
import django |
2 | 2 |
from optparse import NO_DEFAULT |
3 | 3 | |
4 |
if django.VERSION >= (1, 7, 0): |
|
5 |
from django.core.management.commands.migrate import Command as MigrateCommand |
|
6 |
from django.db.migrations.recorder import MigrationRecorder |
|
4 |
from django.core.management.commands.migrate import Command as MigrateCommand |
|
5 |
from django.db.migrations.recorder import MigrationRecorder |
|
7 | 6 |
from django.db import connection |
8 | 7 |
from django.conf import settings |
9 | 8 | |
... | ... | |
15 | 14 |
class MigrateSchemasCommand(SyncCommon): |
16 | 15 |
help = "Updates database schema. Manages both apps with migrations and those without." |
17 | 16 | |
18 |
def __init__(self, stdout=None, stderr=None, no_color=False): |
|
19 |
""" |
|
20 |
Changes the option_list to use the options from the wrapped migrate command. |
|
21 |
""" |
|
22 |
if django.VERSION <= (1, 10, 0): |
|
23 |
self.option_list += MigrateCommand.option_list |
|
24 |
if django.VERSION >= (1, 8, 0): |
|
25 |
super(MigrateSchemasCommand, self).__init__(stdout, stderr, no_color) |
|
26 |
else: |
|
27 |
super(MigrateSchemasCommand, self).__init__() |
|
28 | ||
29 | 17 |
def add_arguments(self, parser): |
30 | 18 |
super(MigrateSchemasCommand, self).add_arguments(parser) |
31 | 19 |
command = MigrateCommand() |
... | ... | |
64 | 52 |
def _notice(self, output): |
65 | 53 |
self.stdout.write(self.style.NOTICE(output)) |
66 | 54 | |
67 | ||
68 |
if django.VERSION >= (1, 7, 0): |
|
69 |
Command = MigrateSchemasCommand |
|
70 |
else: |
|
71 |
from .legacy.migrate_schemas import Command |
|
55 |
Command = MigrateSchemasCommand |
hobo/multitenant/management/commands/safemigrate_schemas.py | ||
---|---|---|
1 |
# this file derive from django-tenant-schemas |
|
2 |
# Author: Bernardo Pires Carneiro |
|
3 |
# Email: carneiro.be@gmail.com |
|
4 |
# License: MIT license |
|
5 |
# Home-page: http://github.com/bcarneiro/django-tenant-schemas |
|
6 |
import django |
|
7 | ||
8 |
if django.VERSION < (1, 7, 0): |
|
9 |
from django.conf import settings |
|
10 |
from django.db import connection |
|
11 |
from south import migration |
|
12 |
from south.migration.base import Migrations |
|
13 |
from hobo.multitenant.middleware import TenantMiddleware |
|
14 |
from entrouvert.djommon.management.commands.safemigrate import Command as SafeMigrateCommand |
|
15 |
from hobo.multitenant.management.commands.sync_schemas import Command as MTSyncCommand |
|
16 |
from hobo.multitenant.management.commands.migrate_schemas import Command as MTMigrateCommand |
|
17 |
from hobo.multitenant.management.commands import SyncCommon |
|
18 | ||
19 | ||
20 |
class SafeMigrateCommand(SyncCommon): |
|
21 |
help = "Safely migrate schemas with South" |
|
22 |
option_list = MTMigrateCommand.option_list |
|
23 | ||
24 |
def handle(self, *args, **options): |
|
25 |
super(Command, self).handle(*args, **options) |
|
26 | ||
27 |
MTSyncCommand().execute(*args, **options) |
|
28 |
connection.set_schema_to_public() |
|
29 |
if self.sync_public: |
|
30 |
self.fake_public_apps() |
|
31 |
if self.sync_tenant: |
|
32 |
self.fake_tenant_apps(self.domain) |
|
33 |
connection.set_schema_to_public() |
|
34 |
MTMigrateCommand().execute(*args, **options) |
|
35 | ||
36 |
def _set_managed_apps(self, included_apps, excluded_apps): |
|
37 |
""" while sync_schemas works by setting which apps are managed, on south we set which apps should be ignored """ |
|
38 |
ignored_apps = [] |
|
39 |
if excluded_apps: |
|
40 |
for item in excluded_apps: |
|
41 |
if item not in included_apps: |
|
42 |
ignored_apps.append(item) |
|
43 | ||
44 |
for app in ignored_apps: |
|
45 |
app_label = app.split('.')[-1] |
|
46 |
settings.SOUTH_MIGRATION_MODULES[app_label] = 'ignore' |
|
47 | ||
48 |
def _save_south_settings(self): |
|
49 |
self._old_south_modules = None |
|
50 |
if hasattr(settings, "SOUTH_MIGRATION_MODULES") and settings.SOUTH_MIGRATION_MODULES is not None: |
|
51 |
self._old_south_modules = settings.SOUTH_MIGRATION_MODULES.copy() |
|
52 |
else: |
|
53 |
settings.SOUTH_MIGRATION_MODULES = dict() |
|
54 | ||
55 |
def _restore_south_settings(self): |
|
56 |
settings.SOUTH_MIGRATION_MODULES = self._old_south_modules |
|
57 | ||
58 |
def _clear_south_cache(self): |
|
59 |
for mig in list(migration.all_migrations()): |
|
60 |
delattr(mig._application, "migrations") |
|
61 |
Migrations._clear_cache() |
|
62 | ||
63 |
def _fake_schema(self, tenant): |
|
64 |
connection.set_tenant(tenant, include_public=False) |
|
65 |
SafeMigrateCommand().fake_if_needed() |
|
66 | ||
67 |
def fake_tenant_apps(self, schema_name=None): |
|
68 |
self._save_south_settings() |
|
69 | ||
70 |
apps = self.tenant_apps or self.installed_apps |
|
71 |
self._set_managed_apps(included_apps=apps, excluded_apps=self.shared_apps) |
|
72 | ||
73 |
if schema_name: |
|
74 |
self._notice("=== Running fake_if_needed for schema: %s" % schema_name) |
|
75 |
connection.set_schema_to_public() |
|
76 |
tenant = TenantMiddleware.get_tenant_by_hostname(schema_name) |
|
77 |
self._fake_schema(tenant) |
|
78 |
else: |
|
79 |
all_tenants = TenantMiddleware.get_tenants() |
|
80 |
if not all_tenants: |
|
81 |
self._notice("No tenants found") |
|
82 | ||
83 |
for tenant in all_tenants: |
|
84 |
Migrations._dependencies_done = False # very important, the dependencies need to be purged from cache |
|
85 |
self._notice("=== Running fake_if_needed for schema %s" % tenant.schema_name) |
|
86 |
self._fake_schema(tenant) |
|
87 | ||
88 |
self._restore_south_settings() |
|
89 | ||
90 |
def fake_public_apps(self): |
|
91 |
self._save_south_settings() |
|
92 | ||
93 |
apps = self.shared_apps or self.installed_apps |
|
94 |
self._set_managed_apps(included_apps=apps, excluded_apps=self.tenant_apps) |
|
95 | ||
96 |
self._notice("=== Running fake_if_needed for schema public") |
|
97 |
SafeMigrateCommand().fake_if_needed() |
|
98 | ||
99 |
self._clear_south_cache() |
|
100 |
self._restore_south_settings() |
|
101 | ||
102 |
if django.VERSION < (1, 7, 0): |
|
103 |
Command = SafeMigrateCommand |
|
104 |
else: |
|
105 |
raise RuntimeError('Django 1.7: please use migrate_schemas') |
hobo/multitenant/management/commands/sync_schemas.py | ||
---|---|---|
1 |
# this file derive from django-tenant-schemas |
|
2 |
# Author: Bernardo Pires Carneiro |
|
3 |
# Email: carneiro.be@gmail.com |
|
4 |
# License: MIT license |
|
5 |
# Home-page: http://github.com/bcarneiro/django-tenant-schemas |
|
6 |
import django |
|
7 |
from django.core.management.base import CommandError |
|
8 | ||
9 |
from django.conf import settings |
|
10 |
from django.contrib.contenttypes.models import ContentType |
|
11 |
from django.db.models import get_apps, get_models |
|
12 |
if 'south' in settings.INSTALLED_APPS: |
|
13 |
from south.management.commands.syncdb import Command as SyncdbCommand |
|
14 |
else: |
|
15 |
from django.core.management.commands.syncdb import Command as SyncdbCommand |
|
16 |
from django.db import connection |
|
17 |
from hobo.multitenant.middleware import TenantMiddleware |
|
18 |
from hobo.multitenant.management.commands import SyncCommon |
|
19 | ||
20 | ||
21 |
class Command(SyncCommon): |
|
22 |
help = "Sync schemas based on TENANT_APPS and SHARED_APPS settings" |
|
23 |
option_list = SyncdbCommand.option_list + SyncCommon.option_list |
|
24 | ||
25 |
def handle(self, *args, **options): |
|
26 |
if django.VERSION >= (1, 7, 0): |
|
27 |
raise CommandError('This command is only meant to be used for 1.6' |
|
28 |
' and older version of django. For 1.7, use' |
|
29 |
' `migrate_schemas` instead.') |
|
30 |
super(Command, self).handle(*args, **options) |
|
31 | ||
32 |
if "south" in settings.INSTALLED_APPS: |
|
33 |
self.options["migrate"] = False |
|
34 | ||
35 |
# save original settings |
|
36 |
for model in get_models(include_auto_created=True): |
|
37 |
setattr(model._meta, 'was_managed', model._meta.managed) |
|
38 | ||
39 |
ContentType.objects.clear_cache() |
|
40 | ||
41 |
if self.sync_public: |
|
42 |
self.sync_public_apps() |
|
43 |
if self.sync_tenant: |
|
44 |
self.sync_tenant_apps(self.domain) |
|
45 | ||
46 |
# restore settings |
|
47 |
for model in get_models(include_auto_created=True): |
|
48 |
model._meta.managed = model._meta.was_managed |
|
49 | ||
50 |
def _set_managed_apps(self, included_apps): |
|
51 |
""" sets which apps are managed by syncdb """ |
|
52 |
for model in get_models(include_auto_created=True): |
|
53 |
model._meta.managed = False |
|
54 | ||
55 |
verbosity = int(self.options.get('verbosity')) |
|
56 |
for app_model in get_apps(): |
|
57 |
app_name = app_model.__name__.replace('.models', '') |
|
58 |
if app_name in included_apps: |
|
59 |
for model in get_models(app_model, include_auto_created=True): |
|
60 |
model._meta.managed = model._meta.was_managed |
|
61 |
if model._meta.managed and verbosity >= 3: |
|
62 |
self._notice("=== Include Model: %s: %s" % (app_name, model.__name__)) |
|
63 | ||
64 |
def _sync_tenant(self, tenant): |
|
65 |
self._notice("=== Running syncdb for schema: %s" % tenant.schema_name) |
|
66 |
connection.set_tenant(tenant, include_public=False) |
|
67 |
SyncdbCommand().execute(**self.options) |
|
68 | ||
69 |
def sync_tenant_apps(self, schema_name=None): |
|
70 |
apps = self.tenant_apps or self.installed_apps |
|
71 |
self._set_managed_apps(apps) |
|
72 |
if schema_name: |
|
73 |
tenant = TenantMiddleware.get_tenant_by_hostname(schema_name) |
|
74 |
self._sync_tenant(tenant) |
|
75 |
else: |
|
76 |
all_tenants = TenantMiddleware.get_tenants() |
|
77 |
if not all_tenants: |
|
78 |
self._notice("No tenants found!") |
|
79 | ||
80 |
for tenant in all_tenants: |
|
81 |
self._sync_tenant(tenant) |
|
82 | ||
83 |
def sync_public_apps(self): |
|
84 |
self._notice("=== Running syncdb for schema public") |
|
85 |
apps = self.shared_apps or self.installed_apps |
|
86 |
self._set_managed_apps(apps) |
|
87 |
SyncdbCommand().execute(**self.options) |
|
88 |
- |