Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #5610 -- Added the ability for dumpdata to take individual mode…

…l names, as well as entire applications. Thanks to David Reynolds for his work on this patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9921 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit db2a95f6f58f5593dbcee8dcf51f3e9d71449708 1 parent b337884
Russell Keith-Magee authored February 28, 2009
44  django/core/management/commands/dumpdata.py
... ...
@@ -1,3 +1,4 @@
  1
+from django.core.exceptions import ImproperlyConfigured
1 2
 from django.core.management.base import BaseCommand, CommandError
2 3
 from django.core import serializers
3 4
 
@@ -9,14 +10,14 @@ class Command(BaseCommand):
9 10
             help='Specifies the output serialization format for fixtures.'),
10 11
         make_option('--indent', default=None, dest='indent', type='int',
11 12
             help='Specifies the indent level to use when pretty-printing output'),
12  
-        make_option('-e', '--exclude', dest='exclude',action='append', default=[], 
  13
+        make_option('-e', '--exclude', dest='exclude',action='append', default=[],
13 14
             help='App to exclude (use multiple --exclude to exclude multiple apps).'),
14 15
     )
15 16
     help = 'Output the contents of the database as a fixture of the given format.'
16 17
     args = '[appname ...]'
17 18
 
18 19
     def handle(self, *app_labels, **options):
19  
-        from django.db.models import get_app, get_apps, get_models
  20
+        from django.db.models import get_app, get_apps, get_models, get_model
20 21
 
21 22
         format = options.get('format','json')
22 23
         indent = options.get('indent',None)
@@ -26,9 +27,34 @@ def handle(self, *app_labels, **options):
26 27
         excluded_apps = [get_app(app_label) for app_label in exclude]
27 28
 
28 29
         if len(app_labels) == 0:
29  
-            app_list = [app for app in get_apps() if app not in excluded_apps]
  30
+            app_list = dict([(app, None) for app in get_apps() if app not in excluded_apps])
30 31
         else:
31  
-            app_list = [get_app(app_label) for app_label in app_labels]
  32
+            app_list = {}
  33
+            for label in app_labels:
  34
+                try:
  35
+                    app_label, model_label = label.split('.')
  36
+                    try:
  37
+                        app = get_app(app_label)
  38
+                    except ImproperlyConfigured:
  39
+                        raise CommandError("Unknown application: %s" % app_label)
  40
+
  41
+                    model = get_model(app_label, model_label)
  42
+                    if model is None:
  43
+                        raise CommandError("Unknown model: %s.%s" % (app_label, model_label))
  44
+
  45
+                    if app in app_list.keys():
  46
+                        if app_list[app] and model not in app_list[app]:
  47
+                            app_list[app].append(model)
  48
+                    else:
  49
+                        app_list[app] = [model]
  50
+                except ValueError:
  51
+                    # This is just an app - no model qualifier
  52
+                    app_label = label
  53
+                    try:
  54
+                        app = get_app(app_label)
  55
+                    except ImproperlyConfigured:
  56
+                        raise CommandError("Unknown application: %s" % app_label)
  57
+                    app_list[app] = None
32 58
 
33 59
         # Check that the serialization format exists; this is a shortcut to
34 60
         # avoid collating all the objects and _then_ failing.
@@ -41,9 +67,13 @@ def handle(self, *app_labels, **options):
41 67
             raise CommandError("Unknown serialization format: %s" % format)
42 68
 
43 69
         objects = []
44  
-        for app in app_list:
45  
-            for model in get_models(app):
46  
-                objects.extend(model._default_manager.all())
  70
+        for app, model_list in app_list.items():
  71
+            if model_list is None:
  72
+                model_list = get_models(app)
  73
+
  74
+            for model in model_list:
  75
+                objects.extend(model.objects.all())
  76
+
47 77
         try:
48 78
             return serializers.serialize(format, objects, indent=indent)
49 79
         except Exception, e:
10  docs/ref/django-admin.txt
@@ -186,7 +186,7 @@ if you're ever curious to see the full list of defaults.
186 186
 dumpdata
187 187
 --------
188 188
 
189  
-.. django-admin:: dumpdata <appname appname ...>
  189
+.. django-admin:: dumpdata <appname appname appname.Model ...>
190 190
 
191 191
 Outputs to standard output all data in the database associated with the named
192 192
 application(s).
@@ -228,6 +228,14 @@ directives::
228 228
     easy for humans to read, so you can use the ``--indent`` option to
229 229
     pretty-print the output with a number of indentation spaces.
230 230
 
  231
+.. versionadded: 1.1
  232
+
  233
+In addition to specifying application names, you can provide a list of
  234
+individual models, in the form of ``appname.Model``. If you specify a model
  235
+name to ``dumpdata``, the dumped output will be restricted to that model,
  236
+rather than the entire application. You can also mix application names and
  237
+model names.
  238
+
231 239
 flush
232 240
 -----
233 241
 
30  tests/modeltests/fixtures/fixtures/fixture1.json
... ...
@@ -1,18 +1,34 @@
1 1
 [
2 2
     {
3  
-        "pk": "2", 
4  
-        "model": "fixtures.article", 
  3
+        "pk": 1,
  4
+        "model": "sites.site",
5 5
         "fields": {
6  
-            "headline": "Poker has no place on ESPN", 
  6
+            "domain": "example.com",
  7
+            "name": "example.com"
  8
+        }
  9
+    },
  10
+    {
  11
+        "pk": "2",
  12
+        "model": "fixtures.article",
  13
+        "fields": {
  14
+            "headline": "Poker has no place on ESPN",
7 15
             "pub_date": "2006-06-16 12:00:00"
8 16
         }
9  
-    }, 
  17
+    },
10 18
     {
11  
-        "pk": "3", 
12  
-        "model": "fixtures.article", 
  19
+        "pk": "3",
  20
+        "model": "fixtures.article",
13 21
         "fields": {
14  
-            "headline": "Time to reform copyright", 
  22
+            "headline": "Time to reform copyright",
15 23
             "pub_date": "2006-06-16 13:00:00"
16 24
         }
  25
+    },
  26
+    {
  27
+        "pk": 1,
  28
+        "model": "fixtures.category",
  29
+        "fields": {
  30
+            "description": "Latest news stories",
  31
+            "title": "News Stories"
  32
+        }
17 33
     }
18 34
 ]
45  tests/modeltests/fixtures/models.py
@@ -11,6 +11,16 @@
11 11
 from django.db import models
12 12
 from django.conf import settings
13 13
 
  14
+class Category(models.Model):
  15
+    title = models.CharField(max_length=100)
  16
+    description = models.TextField()
  17
+
  18
+    def __unicode__(self):
  19
+        return self.title
  20
+
  21
+    class Meta:
  22
+        ordering = ('title',)
  23
+
14 24
 class Article(models.Model):
15 25
     headline = models.CharField(max_length=100, default='Default headline')
16 26
     pub_date = models.DateTimeField()
@@ -38,6 +48,38 @@ class Meta:
38 48
 >>> Article.objects.all()
39 49
 [<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]
40 50
 
  51
+# Dump the current contents of the database as a JSON fixture
  52
+>>> management.call_command('dumpdata', 'fixtures', format='json')
  53
+[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
  54
+
  55
+# Try just dumping the contents of fixtures.Category
  56
+>>> management.call_command('dumpdata', 'fixtures.Category', format='json')
  57
+[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}]
  58
+
  59
+# ...and just fixtures.Article
  60
+>>> management.call_command('dumpdata', 'fixtures.Article', format='json')
  61
+[{"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
  62
+
  63
+# ...and both
  64
+>>> management.call_command('dumpdata', 'fixtures.Category', 'fixtures.Article', format='json')
  65
+[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
  66
+
  67
+# Specify a specific model twice
  68
+>>> management.call_command('dumpdata', 'fixtures.Article', 'fixtures.Article', format='json')
  69
+[{"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
  70
+
  71
+# Specify a dump that specifies Article both explicitly and implicitly
  72
+>>> management.call_command('dumpdata', 'fixtures.Article', 'fixtures', format='json')
  73
+[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
  74
+
  75
+# Same again, but specify in the reverse order
  76
+>>> management.call_command('dumpdata', 'fixtures', 'fixtures.Article', format='json')
  77
+[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
  78
+
  79
+# Specify one model from one application, and an entire other application.
  80
+>>> management.call_command('dumpdata', 'fixtures.Category', 'sites', format='json')
  81
+[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}]
  82
+
41 83
 # Load fixture 2. JSON file imported by default. Overwrites some existing objects
42 84
 >>> management.call_command('loaddata', 'fixture2.json', verbosity=0)
43 85
 >>> Article.objects.all()
@@ -82,7 +124,7 @@ class Meta:
82 124
 
83 125
 # Dump the current contents of the database as a JSON fixture
84 126
 >>> management.call_command('dumpdata', 'fixtures', format='json')
85  
-[{"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
  127
+[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Time to reform copyright", "pub_date": "2006-06-16 13:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker has no place on ESPN", "pub_date": "2006-06-16 12:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}]
86 128
 
87 129
 # Load fixture 4 (compressed), using format discovery
88 130
 >>> management.call_command('loaddata', 'fixture4', verbosity=0)
@@ -116,6 +158,7 @@ class Meta:
116 158
 # because there are two fixture5's in the fixtures directory
117 159
 >>> management.call_command('loaddata', 'fixture5', verbosity=0) # doctest: +ELLIPSIS
118 160
 Multiple fixtures named 'fixture5' in '...fixtures'. Aborting.
  161
+
119 162
 """
120 163
 
121 164
 from django.test import TestCase

0 notes on commit db2a95f

Please sign in to comment.
Something went wrong with that request. Please try again.