Fixed #14162 - Dumpdata needs an option to use the base manager instead of the default manager

Thanks to PaulM for suggestion and patch.



git-svn-id: http://code.djangoproject.com/svn/django/trunk@13669 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Luke Plant 2010-08-30 11:58:26 +00:00
parent f9d051d5f0
commit 5deb3e5a62
4 changed files with 37 additions and 5 deletions

View File

@ -19,9 +19,12 @@ class Command(BaseCommand):
help='An appname or appname.ModelName to exclude (use multiple --exclude to exclude multiple apps/models).'),
make_option('-n', '--natural', action='store_true', dest='use_natural_keys', default=False,
help='Use natural keys if they are available.'),
make_option('-a', '--all', action='store_true', dest='use_base_manager', default=False,
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."),
)
help = ("Output the contents of the database as a fixture of the given "
"format (using each model's default manager).")
"format (using each model's default manager unless --all is "
"specified).")
args = '[appname appname.ModelName ...]'
def handle(self, *app_labels, **options):
@ -34,6 +37,7 @@ class Command(BaseCommand):
excludes = options.get('exclude',[])
show_traceback = options.get('traceback', False)
use_natural_keys = options.get('use_natural_keys', False)
use_base_manager = options.get('use_base_manager', False)
excluded_apps = set()
excluded_models = set()
@ -100,6 +104,9 @@ class Command(BaseCommand):
if model in excluded_models:
continue
if not model._meta.proxy and router.allow_syncdb(using, model):
if use_base_manager:
objects.extend(model._base_manager.using(using).all())
else:
objects.extend(model._default_manager.using(using).all())
try:

View File

@ -208,6 +208,12 @@ records to dump. If you're using a :ref:`custom manager <custom-managers>` as
the default manager and it filters some of the available records, not all of the
objects will be dumped.
.. versionadded:: 1.3
The :djadminopt:`--all` option may be provided to specify that
``dumpdata`` should use Django's base manager, dumping records which
might otherwise be filtered or modified by a custom manager.
.. django-admin-option:: --format <fmt>
By default, ``dumpdata`` will format its output in JSON, but you can use the
@ -271,7 +277,6 @@ prompts.
The :djadminopt:`--database` option may be used to specify the database
to flush.
inspectdb
---------

View File

@ -72,6 +72,14 @@ class Person(models.Model):
def natural_key(self):
return (self.name,)
class SpyManager(PersonManager):
def get_query_set(self):
return super(SpyManager, self).get_query_set().filter(cover_blown=False)
class Spy(Person):
objects = SpyManager()
cover_blown = models.BooleanField(default=False)
class Visa(models.Model):
person = models.ForeignKey(Person)
permissions = models.ManyToManyField(Permission, blank=True)

View File

@ -6,7 +6,7 @@ from django.conf import settings
from django.core import management
from django.db import DEFAULT_DB_ALIAS
from models import Article, Blog, Book, Category, Person, Tag, Visa
from models import Article, Blog, Book, Category, Person, Spy, Tag, Visa
class TestCaseFixtureLoadingTests(TestCase):
fixtures = ['fixture1.json', 'fixture2.json']
@ -24,12 +24,13 @@ class TestCaseFixtureLoadingTests(TestCase):
class FixtureLoadingTests(TestCase):
def _dumpdata_assert(self, args, output, format='json', natural_keys=False,
exclude_list=[]):
use_base_manager=False, exclude_list=[]):
new_io = StringIO.StringIO()
management.call_command('dumpdata', *args, **{'format':format,
'stdout':new_io,
'stderr':new_io,
'use_natural_keys':natural_keys,
'use_base_manager':use_base_manager,
'exclude': exclude_list})
command_output = new_io.getvalue().strip()
self.assertEqual(command_output, output)
@ -197,6 +198,17 @@ class FixtureLoadingTests(TestCase):
'',
exclude_list=['fixtures.FooModel'])
def test_dumpdata_with_filtering_manager(self):
Spy(name='Paul').save()
Spy(name='Alex', cover_blown=True).save()
self.assertQuerysetEqual(Spy.objects.all(),
['<Spy: Paul>'])
# Use the default manager
self._dumpdata_assert(['fixtures.Spy'],'[{"pk": 1, "model": "fixtures.spy", "fields": {"cover_blown": false}}]')
# Dump using Django's base manager. Should return all objects,
# even those normally filtered by the manager
self._dumpdata_assert(['fixtures.Spy'], '[{"pk": 2, "model": "fixtures.spy", "fields": {"cover_blown": true}}, {"pk": 1, "model": "fixtures.spy", "fields": {"cover_blown": false}}]', use_base_manager=True)
def test_compress_format_loading(self):
# Load fixture 4 (compressed), using format specification
management.call_command('loaddata', 'fixture4.json', verbosity=0, commit=False)