~ubuntu-branches/debian/sid/python-django/sid

« back to all changes in this revision

Viewing changes to django/core/management/commands/dumpdata.py

  • Committer: Package Import Robot
  • Author(s): Raphaël Hertzog
  • Date: 2014-09-17 14:15:11 UTC
  • mfrom: (1.3.17) (6.2.18 experimental)
  • Revision ID: package-import@ubuntu.com-20140917141511-icneokthe9ww5sk4
Tags: 1.7-2
* Release to unstable.
* Add a migrate-south sample script to help users apply their South
  migrations. Thanks to Brian May.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from django.core.exceptions import ImproperlyConfigured
 
1
import warnings
 
2
 
 
3
from collections import OrderedDict
 
4
from optparse import make_option
 
5
 
 
6
from django.apps import apps
2
7
from django.core.management.base import BaseCommand, CommandError
3
8
from django.core import serializers
4
9
from django.db import router, DEFAULT_DB_ALIAS
5
 
from django.utils.datastructures import SortedDict
 
10
from django.utils.deprecation import RemovedInDjango19Warning
6
11
 
7
 
from optparse import make_option
8
12
 
9
13
class Command(BaseCommand):
10
14
    option_list = BaseCommand.option_list + (
13
17
        make_option('--indent', default=None, dest='indent', type='int',
14
18
            help='Specifies the indent level to use when pretty-printing output'),
15
19
        make_option('--database', action='store', dest='database',
16
 
            default=DEFAULT_DB_ALIAS, help='Nominates a specific database to dump '
17
 
                'fixtures from. Defaults to the "default" database.'),
18
 
        make_option('-e', '--exclude', dest='exclude',action='append', default=[],
19
 
            help='An appname or appname.ModelName to exclude (use multiple --exclude to exclude multiple apps/models).'),
 
20
            default=DEFAULT_DB_ALIAS,
 
21
            help='Nominates a specific database to dump fixtures from. '
 
22
                 'Defaults to the "default" database.'),
 
23
        make_option('-e', '--exclude', dest='exclude', action='append', default=[],
 
24
            help='An app_label or app_label.ModelName to exclude '
 
25
                 '(use multiple --exclude to exclude multiple apps/models).'),
20
26
        make_option('-n', '--natural', action='store_true', dest='use_natural_keys', default=False,
21
 
            help='Use natural keys if they are available.'),
 
27
            help='Use natural keys if they are available (deprecated: use --natural-foreign instead).'),
 
28
        make_option('--natural-foreign', action='store_true', dest='use_natural_foreign_keys', default=False,
 
29
            help='Use natural foreign keys if they are available.'),
 
30
        make_option('--natural-primary', action='store_true', dest='use_natural_primary_keys', default=False,
 
31
            help='Use natural primary keys if they are available.'),
22
32
        make_option('-a', '--all', action='store_true', dest='use_base_manager', default=False,
23
 
            help="Use Django's base manager to dump all models stored in the database, including those that would otherwise be filtered or modified by a custom manager."),
24
 
        make_option('--pks', dest='primary_keys', help="Only dump objects with "
25
 
            "given primary keys. Accepts a comma seperated list of keys. "
26
 
            "This option will only work when you specify one model."),
 
33
            help="Use Django's base manager to dump all models stored in the database, "
 
34
                 "including those that would otherwise be filtered or modified by a custom manager."),
 
35
        make_option('--pks', dest='primary_keys',
 
36
            help="Only dump objects with given primary keys. "
 
37
                 "Accepts a comma separated list of keys. "
 
38
                 "This option will only work when you specify one model."),
27
39
    )
28
40
    help = ("Output the contents of the database as a fixture of the given "
29
41
            "format (using each model's default manager unless --all is "
30
42
            "specified).")
31
 
    args = '[appname appname.ModelName ...]'
 
43
    args = '[app_label app_label.ModelName ...]'
32
44
 
33
45
    def handle(self, *app_labels, **options):
34
 
        from django.db.models import get_app, get_apps, get_model
35
 
 
36
46
        format = options.get('format')
37
47
        indent = options.get('indent')
38
48
        using = options.get('database')
39
49
        excludes = options.get('exclude')
40
50
        show_traceback = options.get('traceback')
41
51
        use_natural_keys = options.get('use_natural_keys')
 
52
        if use_natural_keys:
 
53
            warnings.warn("``--natural`` is deprecated; use ``--natural-foreign`` instead.",
 
54
                RemovedInDjango19Warning)
 
55
        use_natural_foreign_keys = options.get('use_natural_foreign_keys') or use_natural_keys
 
56
        use_natural_primary_keys = options.get('use_natural_primary_keys')
42
57
        use_base_manager = options.get('use_base_manager')
43
58
        pks = options.get('primary_keys')
44
59
 
51
66
        excluded_models = set()
52
67
        for exclude in excludes:
53
68
            if '.' in exclude:
54
 
                app_label, model_name = exclude.split('.', 1)
55
 
                model_obj = get_model(app_label, model_name)
56
 
                if not model_obj:
 
69
                try:
 
70
                    model = apps.get_model(exclude)
 
71
                except LookupError:
57
72
                    raise CommandError('Unknown model in excludes: %s' % exclude)
58
 
                excluded_models.add(model_obj)
 
73
                excluded_models.add(model)
59
74
            else:
60
75
                try:
61
 
                    app_obj = get_app(exclude)
62
 
                    excluded_apps.add(app_obj)
63
 
                except ImproperlyConfigured:
 
76
                    app_config = apps.get_app_config(exclude)
 
77
                except LookupError:
64
78
                    raise CommandError('Unknown app in excludes: %s' % exclude)
 
79
                excluded_apps.add(app_config)
65
80
 
66
81
        if len(app_labels) == 0:
67
82
            if primary_keys:
68
83
                raise CommandError("You can only use --pks option with one model")
69
 
            app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps)
 
84
            app_list = OrderedDict((app_config, None)
 
85
                for app_config in apps.get_app_configs()
 
86
                if app_config.models_module is not None and app_config not in excluded_apps)
70
87
        else:
71
88
            if len(app_labels) > 1 and primary_keys:
72
89
                raise CommandError("You can only use --pks option with one model")
73
 
            app_list = SortedDict()
 
90
            app_list = OrderedDict()
74
91
            for label in app_labels:
75
92
                try:
76
93
                    app_label, model_label = label.split('.')
77
94
                    try:
78
 
                        app = get_app(app_label)
79
 
                    except ImproperlyConfigured:
 
95
                        app_config = apps.get_app_config(app_label)
 
96
                    except LookupError:
80
97
                        raise CommandError("Unknown application: %s" % app_label)
81
 
                    if app in excluded_apps:
 
98
                    if app_config.models_module is None or app_config in excluded_apps:
82
99
                        continue
83
 
                    model = get_model(app_label, model_label)
84
 
                    if model is None:
 
100
                    try:
 
101
                        model = app_config.get_model(model_label)
 
102
                    except LookupError:
85
103
                        raise CommandError("Unknown model: %s.%s" % (app_label, model_label))
86
104
 
87
 
                    if app in app_list.keys():
88
 
                        if app_list[app] and model not in app_list[app]:
89
 
                            app_list[app].append(model)
90
 
                    else:
91
 
                        app_list[app] = [model]
 
105
                    app_list_value = app_list.setdefault(app_config, [])
 
106
 
 
107
                    # We may have previously seen a "all-models" request for
 
108
                    # this app (no model qualifier was given). In this case
 
109
                    # there is no need adding specific models to the list.
 
110
                    if app_list_value is not None:
 
111
                        if model not in app_list_value:
 
112
                            app_list_value.append(model)
92
113
                except ValueError:
93
114
                    if primary_keys:
94
115
                        raise CommandError("You can only use --pks option with one model")
95
116
                    # This is just an app - no model qualifier
96
117
                    app_label = label
97
118
                    try:
98
 
                        app = get_app(app_label)
99
 
                    except ImproperlyConfigured:
 
119
                        app_config = apps.get_app_config(app_label)
 
120
                    except LookupError:
100
121
                        raise CommandError("Unknown application: %s" % app_label)
101
 
                    if app in excluded_apps:
 
122
                    if app_config.models_module is None or app_config in excluded_apps:
102
123
                        continue
103
 
                    app_list[app] = None
 
124
                    app_list[app_config] = None
104
125
 
105
126
        # Check that the serialization format exists; this is a shortcut to
106
127
        # avoid collating all the objects and _then_ failing.
117
138
            for model in sort_dependencies(app_list.items()):
118
139
                if model in excluded_models:
119
140
                    continue
120
 
                if not model._meta.proxy and router.allow_syncdb(using, model):
 
141
                if not model._meta.proxy and router.allow_migrate(using, model):
121
142
                    if use_base_manager:
122
143
                        objects = model._base_manager
123
144
                    else:
132
153
        try:
133
154
            self.stdout.ending = None
134
155
            serializers.serialize(format, get_objects(), indent=indent,
135
 
                    use_natural_keys=use_natural_keys, stream=self.stdout)
 
156
                    use_natural_foreign_keys=use_natural_foreign_keys,
 
157
                    use_natural_primary_keys=use_natural_primary_keys,
 
158
                    stream=self.stdout)
136
159
        except Exception as e:
137
160
            if show_traceback:
138
161
                raise
139
162
            raise CommandError("Unable to serialize database: %s" % e)
140
163
 
 
164
 
141
165
def sort_dependencies(app_list):
142
 
    """Sort a list of app,modellist pairs into a single list of models.
 
166
    """Sort a list of (app_config, models) pairs into a single list of models.
143
167
 
144
168
    The single list of models is sorted so that any model with a natural key
145
169
    is serialized before a normal model, and any model with a natural key
146
170
    dependency has it's dependencies serialized first.
147
171
    """
148
 
    from django.db.models import get_model, get_models
149
172
    # Process the list of models, and get the list of dependencies
150
173
    model_dependencies = []
151
174
    models = set()
152
 
    for app, model_list in app_list:
 
175
    for app_config, model_list in app_list:
153
176
        if model_list is None:
154
 
            model_list = get_models(app)
 
177
            model_list = app_config.get_models()
155
178
 
156
179
        for model in model_list:
157
180
            models.add(model)
159
182
            if hasattr(model, 'natural_key'):
160
183
                deps = getattr(model.natural_key, 'dependencies', [])
161
184
                if deps:
162
 
                    deps = [get_model(*d.split('.')) for d in deps]
 
185
                    deps = [apps.get_model(dep) for dep in deps]
163
186
            else:
164
187
                deps = []
165
188