diff options
| author | Konrad Świat <konrad.swiat@gmail.com> | 2014-10-30 18:38:47 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2014-10-31 18:21:54 -0400 |
| commit | 934a16dc93a5f46f965ba299dbd543703d32d493 (patch) | |
| tree | 3d1b84d25f68fc0a26d187fd85d2b099beb15ff1 | |
| parent | e548d08f243335b4f11190417830a5f3027efd2a (diff) | |
Fixed #23468 -- Added checks for duplicate fixtures directories in loaddata.
If settings.FIXTURE_DIRS contains duplicates or a default fixture
directory (app_name/fixtures), ImproperlyConfigured is raised.
Thanks to Berker Peksag and Tim Graham for review.
| -rw-r--r-- | django/core/management/commands/loaddata.py | 17 | ||||
| -rw-r--r-- | docs/releases/1.8.txt | 4 | ||||
| -rw-r--r-- | tests/fixtures_regress/tests.py | 43 |
3 files changed, 61 insertions, 3 deletions
diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index 05cf769489..aae69afc9b 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -9,6 +9,7 @@ import zipfile from django.apps import apps from django.conf import settings from django.core import serializers +from django.core.exceptions import ImproperlyConfigured from django.core.management.base import BaseCommand, CommandError from django.core.management.color import no_style from django.db import (connections, router, transaction, DEFAULT_DB_ALIAS, @@ -238,13 +239,23 @@ class Command(BaseCommand): current directory. """ dirs = [] + fixture_dirs = settings.FIXTURE_DIRS + if len(fixture_dirs) != len(set(fixture_dirs)): + raise ImproperlyConfigured("settings.FIXTURE_DIRS contains duplicates.") for app_config in apps.get_app_configs(): - if self.app_label and app_config.label != self.app_label: - continue + app_label = app_config.label app_dir = os.path.join(app_config.path, 'fixtures') + if app_dir in fixture_dirs: + raise ImproperlyConfigured( + "'%s' is a default fixture directory for the '%s' app " + "and cannot be listed in settings.FIXTURE_DIRS." % (app_dir, app_label) + ) + + if self.app_label and app_label != self.app_label: + continue if os.path.isdir(app_dir): dirs.append(app_dir) - dirs.extend(list(settings.FIXTURE_DIRS)) + dirs.extend(list(fixture_dirs)) dirs.append('') dirs = [upath(os.path.abspath(os.path.realpath(d))) for d in dirs] return dirs diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index d02672be9a..f84294d459 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -284,6 +284,10 @@ Management Commands * The :djadminopt:`--name` option for :djadmin:`makemigrations` allows you to to give the migration(s) a custom name instead of a generated one. +* The :djadmin:`loaddata` command now prevents repeated fixture loading. If + :setting:`FIXTURE_DIRS` contains duplicates or a default fixture directory + path (``app_name/fixtures``), an exception is raised. + Migrations ^^^^^^^^^^ diff --git a/tests/fixtures_regress/tests.py b/tests/fixtures_regress/tests.py index 0ec48bc5e9..171ef30fec 100644 --- a/tests/fixtures_regress/tests.py +++ b/tests/fixtures_regress/tests.py @@ -8,6 +8,7 @@ import re import warnings from django.core import serializers +from django.core.exceptions import ImproperlyConfigured from django.core.serializers.base import DeserializationError from django.core import management from django.core.management.base import CommandError @@ -486,6 +487,48 @@ class TestFixtures(TestCase): verbosity=0, ) + @override_settings(FIXTURE_DIRS=[os.path.join(_cur_dir, 'fixtures_1'), + os.path.join(_cur_dir, 'fixtures_1')]) + def test_fixture_dirs_with_duplicates(self): + """ + settings.FIXTURE_DIRS cannot contain duplicates in order to avoid + repeated fixture loading. + """ + self.assertRaisesMessage( + ImproperlyConfigured, + "settings.FIXTURE_DIRS contains duplicates.", + management.call_command, + 'loaddata', + 'absolute.json', + verbosity=0, + ) + + @override_settings(FIXTURE_DIRS=[os.path.join(_cur_dir, 'fixtures')]) + def test_fixture_dirs_with_default_fixture_path(self): + """ + settings.FIXTURE_DIRS cannot contain a default fixtures directory + for application (app/fixtures) in order to avoid repeated fixture loading. + """ + self.assertRaisesMessage( + ImproperlyConfigured, + "'%s' is a default fixture directory for the '%s' app " + "and cannot be listed in settings.FIXTURE_DIRS." + % (os.path.join(_cur_dir, 'fixtures'), 'fixtures_regress'), + management.call_command, + 'loaddata', + 'absolute.json', + verbosity=0, + ) + + @override_settings(FIXTURE_DIRS=[os.path.join(_cur_dir, 'fixtures_1'), + os.path.join(_cur_dir, 'fixtures_2')]) + def test_loaddata_with_valid_fixture_dirs(self): + management.call_command( + 'loaddata', + 'absolute.json', + verbosity=0, + ) + class NaturalKeyFixtureTests(TestCase): |
