Projet

Général

Profil

0001-multitenant-remove-django-1.8-compatibility-code-fro.patch

Frédéric Péters, 09 août 2018 22:58

Télécharger (19,3 ko)

Voir les différences:

Subject: [PATCH] multitenant: remove django < 1.8 compatibility code from
 commands (#25538)

 .../management/commands/__init__.py           |  33 ------
 .../management/commands/legacy/__init__.py    |   0
 .../commands/legacy/migrate_schemas.py        |  91 ---------------
 .../management/commands/list_tenants.py       |   1 -
 .../management/commands/migrate_schemas.py    |  22 +---
 .../commands/safemigrate_schemas.py           | 105 ------------------
 .../management/commands/sync_schemas.py       |  87 ---------------
 7 files changed, 3 insertions(+), 336 deletions(-)
 delete mode 100644 hobo/multitenant/management/commands/legacy/__init__.py
 delete mode 100644 hobo/multitenant/management/commands/legacy/migrate_schemas.py
 delete mode 100644 hobo/multitenant/management/commands/safemigrate_schemas.py
 delete mode 100644 hobo/multitenant/management/commands/sync_schemas.py
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
-