From c1f45c326c4bdeb8821844f6ee4bfd2817ab6a63 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Fri, 22 Feb 2008 12:50:10 +0000 Subject: [PATCH] Fixed #6436 -- Added check for absolute paths in fixture loading. Fixtures specified as an absolute path were being loaded multiple times. Thanks to btoll@bestweb.net for the report, fix, and catch of a duplicate ticket. git-svn-id: http://code.djangoproject.com/svn/django/trunk@7145 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- AUTHORS | 1 + django/core/management/commands/loaddata.py | 20 +++++++++++------ .../fixtures_regress/fixtures/absolute.json | 9 ++++++++ .../fixtures_regress/models.py | 22 +++++++++++++++++++ 4 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 tests/regressiontests/fixtures_regress/fixtures/absolute.json diff --git a/AUTHORS b/AUTHORS index 47a0646567..9c28d73730 100644 --- a/AUTHORS +++ b/AUTHORS @@ -71,6 +71,7 @@ answer newbie questions, and generally made Django that much better: boobsd@gmail.com Andrew Brehaut brut.alll@gmail.com + btoll@bestweb.net Jonathan Buchanan Can Burak Çilingir Trevor Caira diff --git a/django/core/management/commands/loaddata.py b/django/core/management/commands/loaddata.py index e95be6b8d7..dde9e6eb80 100644 --- a/django/core/management/commands/loaddata.py +++ b/django/core/management/commands/loaddata.py @@ -30,7 +30,8 @@ class Command(BaseCommand): show_traceback = options.get('traceback', False) # Keep a count of the installed objects and fixtures - count = [0, 0] + fixture_count = 0 + object_count = 0 models = set() humanize = lambda dirname: dirname and "'%s'" % dirname or 'absolute path' @@ -65,7 +66,12 @@ class Command(BaseCommand): else: print "Skipping fixture '%s': %s is not a known serialization format" % (fixture_name, format) - for fixture_dir in app_fixtures + list(settings.FIXTURE_DIRS) + ['']: + if os.path.isabs(fixture_name): + fixture_dirs = [fixture_name] + else: + fixture_dirs = app_fixtures + list(settings.FIXTURE_DIRS) + [''] + + for fixture_dir in fixture_dirs: if verbosity > 1: print "Checking %s for fixtures..." % humanize(fixture_dir) @@ -86,14 +92,14 @@ class Command(BaseCommand): transaction.leave_transaction_management() return else: - count[1] += 1 + fixture_count += 1 if verbosity > 0: print "Installing %s fixture '%s' from %s." % \ (format, fixture_name, humanize(fixture_dir)) try: objects = serializers.deserialize(format, fixture) for obj in objects: - count[0] += 1 + object_count += 1 models.add(obj.object.__class__) obj.save() label_found = True @@ -113,7 +119,7 @@ class Command(BaseCommand): print "No %s fixture '%s' in %s." % \ (format, fixture_name, humanize(fixture_dir)) - if count[0] > 0: + if object_count > 0: sequence_sql = connection.ops.sequence_reset_sql(self.style, models) if sequence_sql: if verbosity > 1: @@ -124,9 +130,9 @@ class Command(BaseCommand): transaction.commit() transaction.leave_transaction_management() - if count[0] == 0: + if object_count == 0: if verbosity >= 2: print "No fixtures found." else: if verbosity > 0: - print "Installed %d object(s) from %d fixture(s)" % tuple(count) + print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count) diff --git a/tests/regressiontests/fixtures_regress/fixtures/absolute.json b/tests/regressiontests/fixtures_regress/fixtures/absolute.json new file mode 100644 index 0000000000..37ed3f6886 --- /dev/null +++ b/tests/regressiontests/fixtures_regress/fixtures/absolute.json @@ -0,0 +1,9 @@ +[ + { + "pk": "1", + "model": "fixtures_regress.absolute", + "fields": { + "name": "Load Absolute Path Test" + } + } +] \ No newline at end of file diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py index a62925eb37..144debe05a 100644 --- a/tests/regressiontests/fixtures_regress/models.py +++ b/tests/regressiontests/fixtures_regress/models.py @@ -1,6 +1,7 @@ from django.db import models from django.contrib.auth.models import User from django.conf import settings +import os class Animal(models.Model): name = models.CharField(max_length=150) @@ -28,6 +29,16 @@ class Stuff(models.Model): name = None return unicode(name) + u' is owned by ' + unicode(self.owner) +class Absolute(models.Model): + name = models.CharField(max_length=40) + + load_count = 0 + + def __init__(self, *args, **kwargs): + super(Absolute, self).__init__(*args, **kwargs) + Absolute.load_count += 1 + + __test__ = {'API_TESTS':""" >>> from django.core import management @@ -49,4 +60,15 @@ __test__ = {'API_TESTS':""" >>> Stuff.objects.all() [] +############################################### +# Regression test for ticket #6436 -- +# os.path.join will throw away the initial parts of a path if it encounters +# an absolute path. This means that if a fixture is specified as an absolute path, +# we need to make sure we don't discover the absolute path in every fixture directory. + +>>> load_absolute_path = os.path.join(os.path.dirname(__file__), 'fixtures', 'absolute.json') +>>> management.call_command('loaddata', load_absolute_path, verbosity=0) +>>> Absolute.load_count +1 + """}