Fixed #21969: Fix behaviour of initial_data with migrated apps
This commit is contained in:
parent
250841017c
commit
d5df7a0515
|
@ -35,6 +35,8 @@ class Command(BaseCommand):
|
||||||
make_option('--database', action='store', dest='database',
|
make_option('--database', action='store', dest='database',
|
||||||
default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load '
|
default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load '
|
||||||
'fixtures into. Defaults to the "default" database.'),
|
'fixtures into. Defaults to the "default" database.'),
|
||||||
|
make_option('--app', action='store', dest='app_label',
|
||||||
|
default=None, help='Only look for fixtures in the specified app.'),
|
||||||
make_option('--ignorenonexistent', '-i', action='store_true', dest='ignore',
|
make_option('--ignorenonexistent', '-i', action='store_true', dest='ignore',
|
||||||
default=False, help='Ignores entries in the serialized data for fields'
|
default=False, help='Ignores entries in the serialized data for fields'
|
||||||
' that do not currently exist on the model.'),
|
' that do not currently exist on the model.'),
|
||||||
|
@ -44,6 +46,8 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
self.ignore = options.get('ignore')
|
self.ignore = options.get('ignore')
|
||||||
self.using = options.get('database')
|
self.using = options.get('database')
|
||||||
|
self.app_label = options.get('app_label')
|
||||||
|
self.hide_empty = options.get('hide_empty', False)
|
||||||
|
|
||||||
if not len(fixture_labels):
|
if not len(fixture_labels):
|
||||||
raise CommandError(
|
raise CommandError(
|
||||||
|
@ -105,7 +109,9 @@ class Command(BaseCommand):
|
||||||
cursor.execute(line)
|
cursor.execute(line)
|
||||||
|
|
||||||
if self.verbosity >= 1:
|
if self.verbosity >= 1:
|
||||||
if self.fixture_object_count == self.loaded_object_count:
|
if self.fixture_count == 0 and self.hide_empty:
|
||||||
|
pass
|
||||||
|
elif self.fixture_object_count == self.loaded_object_count:
|
||||||
self.stdout.write("Installed %d object(s) from %d fixture(s)" %
|
self.stdout.write("Installed %d object(s) from %d fixture(s)" %
|
||||||
(self.loaded_object_count, self.fixture_count))
|
(self.loaded_object_count, self.fixture_count))
|
||||||
else:
|
else:
|
||||||
|
@ -230,6 +236,8 @@ class Command(BaseCommand):
|
||||||
"""
|
"""
|
||||||
dirs = []
|
dirs = []
|
||||||
for app_config in apps.get_app_configs():
|
for app_config in apps.get_app_configs():
|
||||||
|
if self.app_label and app_config.label != self.app_label:
|
||||||
|
continue
|
||||||
d = os.path.join(app_config.path, 'fixtures')
|
d = os.path.join(app_config.path, 'fixtures')
|
||||||
if os.path.isdir(d):
|
if os.path.isdir(d):
|
||||||
dirs.append(d)
|
dirs.append(d)
|
||||||
|
|
|
@ -278,7 +278,8 @@ class Command(BaseCommand):
|
||||||
|
|
||||||
# Load initial_data fixtures (unless that has been disabled)
|
# Load initial_data fixtures (unless that has been disabled)
|
||||||
if self.load_initial_data:
|
if self.load_initial_data:
|
||||||
call_command('loaddata', 'initial_data', verbosity=self.verbosity, database=connection.alias, skip_validation=True)
|
for app_label in app_labels:
|
||||||
|
call_command('loaddata', 'initial_data', verbosity=self.verbosity, database=connection.alias, skip_validation=True, app_label=app_label, hide_empty=True)
|
||||||
|
|
||||||
return created_models
|
return created_models
|
||||||
|
|
||||||
|
|
|
@ -383,6 +383,16 @@ onto which the data will be loaded.
|
||||||
The :djadminopt:`--ignorenonexistent` option can be used to ignore fields that
|
The :djadminopt:`--ignorenonexistent` option can be used to ignore fields that
|
||||||
may have been removed from models since the fixture was originally generated.
|
may have been removed from models since the fixture was originally generated.
|
||||||
|
|
||||||
|
|
||||||
|
.. versionchanged:: 1.7
|
||||||
|
|
||||||
|
``--app`` was added.
|
||||||
|
|
||||||
|
.. django-admin-option:: --app
|
||||||
|
|
||||||
|
The :djadminopt:`--app` option can be used to specify a single app to look
|
||||||
|
for fixtures in rather than looking through all apps.
|
||||||
|
|
||||||
What's a "fixture"?
|
What's a "fixture"?
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,9 @@ but a few of the key features are:
|
||||||
will still work, but that method name is deprecated and you should change
|
will still work, but that method name is deprecated and you should change
|
||||||
it as soon as possible (nothing more than renaming is required).
|
it as soon as possible (nothing more than renaming is required).
|
||||||
|
|
||||||
|
* ``initial_data`` fixtures are no longer loaded for apps with migrations; if
|
||||||
|
you want to load initial data for an app, we suggest you do it in a migration.
|
||||||
|
|
||||||
App-loading refactor
|
App-loading refactor
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -714,6 +717,19 @@ For apps with migrations, ``allow_migrate`` will now get passed
|
||||||
without custom attributes, methods or managers. Make sure your ``allow_migrate``
|
without custom attributes, methods or managers. Make sure your ``allow_migrate``
|
||||||
methods are only referring to fields or other items in ``model._meta``.
|
methods are only referring to fields or other items in ``model._meta``.
|
||||||
|
|
||||||
|
initial_data
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Apps with migrations will not load ``initial_data`` fixtures when they have
|
||||||
|
finished migrating. Apps without migrations will continue to load these fixtures
|
||||||
|
during the phase of ``migrate`` which emulates the old ``syncdb`` behaviour,
|
||||||
|
but any new apps will not have this support.
|
||||||
|
|
||||||
|
Instead, you are encouraged to load initial data in migrations if you need it
|
||||||
|
(using the ``RunPython`` operation and your model classes);
|
||||||
|
this has the added advantage that your initial data will not need updating
|
||||||
|
every time you change the schema.
|
||||||
|
|
||||||
App-loading changes
|
App-loading changes
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -329,6 +329,17 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
|
||||||
management.call_command('loaddata', 'invalid.json', verbosity=0)
|
management.call_command('loaddata', 'invalid.json', verbosity=0)
|
||||||
self.assertIn("Could not load fixtures.Article(pk=1):", cm.exception.args[0])
|
self.assertIn("Could not load fixtures.Article(pk=1):", cm.exception.args[0])
|
||||||
|
|
||||||
|
def test_loaddata_app_option(self):
|
||||||
|
"""
|
||||||
|
Verifies that the --app option works.
|
||||||
|
"""
|
||||||
|
management.call_command('loaddata', 'db_fixture_1', verbosity=0, app_label="someotherapp")
|
||||||
|
self.assertQuerysetEqual(Article.objects.all(), [])
|
||||||
|
management.call_command('loaddata', 'db_fixture_1', verbosity=0, app_label="fixtures")
|
||||||
|
self.assertQuerysetEqual(Article.objects.all(), [
|
||||||
|
'<Article: Who needs more than one database?>',
|
||||||
|
])
|
||||||
|
|
||||||
def test_loading_using(self):
|
def test_loading_using(self):
|
||||||
# Load db fixtures 1 and 2. These will load using the 'default' database identifier explicitly
|
# Load db fixtures 1 and 2. These will load using the 'default' database identifier explicitly
|
||||||
management.call_command('loaddata', 'db_fixture_1', verbosity=0, using='default')
|
management.call_command('loaddata', 'db_fixture_1', verbosity=0, using='default')
|
||||||
|
|
Loading…
Reference in New Issue