Ticket #13636: 13636-r13318.diff
File 13636-r13318.diff, 59.7 KB (added by , 14 years ago) |
---|
-
django/core/management/base.py
diff -r fa1e8c79bda8 django/core/management/base.py
a b 213 213 sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) 214 214 sys.exit(1) 215 215 try: 216 self.stdout = options.get('stdout', sys.stdout) 217 self.stderr = options.get('stderr', sys.stderr) 216 218 if self.requires_model_validation: 217 219 self.validate() 218 220 output = self.handle(*args, **options) … … 223 225 from django.db import connections, DEFAULT_DB_ALIAS 224 226 connection = connections[options.get('database', DEFAULT_DB_ALIAS)] 225 227 if connection.ops.start_transaction_sql(): 226 print self.style.SQL_KEYWORD(connection.ops.start_transaction_sql())227 print output228 self.stdout.write(self.style.SQL_KEYWORD(connection.ops.start_transaction_sql())) 229 self.stdout.write(output) 228 230 if self.output_transaction: 229 print self.style.SQL_KEYWORD(connection.ops.end_transaction_sql())231 self.stdout.write(self.style.SQL_KEYWORD("COMMIT;") + '\n') 230 232 except CommandError, e: 231 s ys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))233 self.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e))) 232 234 sys.exit(1) 233 235 234 236 def validate(self, app=None, display_num_errors=False): … … 250 252 error_text = s.read() 251 253 raise CommandError("One or more models did not validate:\n%s" % error_text) 252 254 if display_num_errors: 253 print "%s error%s found" % (num_errors, num_errors != 1 and 's' or '')255 self.stdout.write("%s error%s found\n" % (num_errors, num_errors != 1 and 's' or '')) 254 256 255 257 def handle(self, *args, **options): 256 258 """ -
django/core/management/commands/loaddata.py
diff -r fa1e8c79bda8 django/core/management/commands/loaddata.py
a b 112 112 113 113 if formats: 114 114 if verbosity > 1: 115 print "Loading '%s' fixtures..." % fixture_name115 self.stdout.write("Loading '%s' fixtures...\n" % fixture_name) 116 116 else: 117 117 sys.stderr.write( 118 self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format. " %118 self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format.\n" % 119 119 (fixture_name, format))) 120 120 transaction.rollback(using=using) 121 121 transaction.leave_transaction_management(using=using) … … 128 128 129 129 for fixture_dir in fixture_dirs: 130 130 if verbosity > 1: 131 print "Checking %s for fixtures..." % humanize(fixture_dir)131 self.stdout.write("Checking %s for fixtures...\n" % humanize(fixture_dir)) 132 132 133 133 label_found = False 134 134 for combo in product([using, None], formats, compression_formats): … … 141 141 ) 142 142 143 143 if verbosity > 1: 144 print "Trying %s for %s fixture '%s'..." % \145 (humanize(fixture_dir), file_name, fixture_name) 144 self.stdout.write("Trying %s for %s fixture '%s'...\n" % \ 145 (humanize(fixture_dir), file_name, fixture_name)) 146 146 full_path = os.path.join(fixture_dir, file_name) 147 147 open_method = compression_types[compression_format] 148 148 try: 149 149 fixture = open_method(full_path, 'r') 150 150 if label_found: 151 151 fixture.close() 152 print self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting." %153 (fixture_name, humanize(fixture_dir))) 152 self.stdout.write(self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting.\n" % 153 (fixture_name, humanize(fixture_dir)))) 154 154 transaction.rollback(using=using) 155 155 transaction.leave_transaction_management(using=using) 156 156 return … … 158 158 fixture_count += 1 159 159 objects_in_fixture = 0 160 160 if verbosity > 0: 161 print "Installing %s fixture '%s' from %s." % \162 (format, fixture_name, humanize(fixture_dir)) 161 self.stdout.write("Installing %s fixture '%s' from %s.\n" % \ 162 (format, fixture_name, humanize(fixture_dir))) 163 163 try: 164 164 objects = serializers.deserialize(format, fixture, using=using) 165 165 for obj in objects: … … 190 190 # error was encountered during fixture loading. 191 191 if objects_in_fixture == 0: 192 192 sys.stderr.write( 193 self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.) " %193 self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)\n" % 194 194 (fixture_name))) 195 195 transaction.rollback(using=using) 196 196 transaction.leave_transaction_management(using=using) … … 198 198 199 199 except Exception, e: 200 200 if verbosity > 1: 201 print "No %s fixture '%s' in %s." % \202 (format, fixture_name, humanize(fixture_dir)) 201 self.stdout.write("No %s fixture '%s' in %s.\n" % \ 202 (format, fixture_name, humanize(fixture_dir))) 203 203 204 204 # If we found even one object in a fixture, we need to reset the 205 205 # database sequences. … … 207 207 sequence_sql = connection.ops.sequence_reset_sql(self.style, models) 208 208 if sequence_sql: 209 209 if verbosity > 1: 210 print "Resetting sequences"210 self.stdout.write("Resetting sequences\n") 211 211 for line in sequence_sql: 212 212 cursor.execute(line) 213 213 … … 217 217 218 218 if object_count == 0: 219 219 if verbosity > 0: 220 print "No fixtures found."220 self.stdout.write("No fixtures found.\n") 221 221 else: 222 222 if verbosity > 0: 223 print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)223 self.stdout.write("Installed %d object(s) from %d fixture(s)\n" % (object_count, fixture_count)) 224 224 225 225 # Close the DB connection. This is required as a workaround for an 226 226 # edge case in MySQL: if the same connection is used to -
docs/howto/custom-management-commands.txt
diff -r fa1e8c79bda8 docs/howto/custom-management-commands.txt
a b 8 8 9 9 Applications can register their own actions with ``manage.py``. For example, 10 10 you might want to add a ``manage.py`` action for a Django app that you're 11 distributing. In this document, we will be building a custom ``closepoll`` 11 distributing. In this document, we will be building a custom ``closepoll`` 12 12 command for the ``polls`` application from the 13 13 :ref:`tutorial<intro-tutorial01>`. 14 14 … … 62 62 poll.opened = False 63 63 poll.save() 64 64 65 print 'Successfully closed poll "%s"' % poll_id65 self.stdout.write('Successfully closed poll "%s"\n' % poll_id) 66 66 67 The new custom command can be called using ``python manage.py closepoll 67 .. note:: 68 When you are using management commands and wish to provide console 69 output, you should write to ``self.stdout`` and ``self.stderr``, 70 instead of printing to ``stdout`` and ``stderr`` directly. By 71 using these proxies, it becomes much easier to test your custom 72 command. 73 74 The new custom command can be called using ``python manage.py closepoll 68 75 <poll_id>``. 69 76 70 77 The ``handle()`` method takes zero or more ``poll_ids`` and sets ``poll.opened`` … … 91 98 ) 92 99 # ... 93 100 94 In addition to being able to add custom command line options, all 95 :ref:`management commands<ref-django-admin>` can accept some 101 In addition to being able to add custom command line options, all 102 :ref:`management commands<ref-django-admin>` can accept some 96 103 default options such as :djadminopt:`--verbosity` and :djadminopt:`--traceback`. 97 104 98 105 Command objects … … 113 120 Attributes 114 121 ---------- 115 122 116 All attributes can be set in your derived class and can be used in 123 All attributes can be set in your derived class and can be used in 117 124 :class:`BaseCommand`'s :ref:`subclasses<ref-basecommand-subclasses>`. 118 125 119 126 .. attribute:: BaseCommand.args … … 133 140 .. attribute:: BaseCommand.help 134 141 135 142 A short description of the command, which will be printed in the 136 help message when the user runs the command 143 help message when the user runs the command 137 144 ``python manage.py help <command>``. 138 145 139 146 .. attribute:: BaseCommand.option_list … … 230 237 A command which takes no arguments on the command line. 231 238 232 239 Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement 233 :meth:`~NoArgsCommand.handle_noargs`; :meth:`~BaseCommand.handle` itself is 240 :meth:`~NoArgsCommand.handle_noargs`; :meth:`~BaseCommand.handle` itself is 234 241 overridden to ensure no arguments are passed to the command. 235 242 236 243 .. method:: NoArgsCommand.handle_noargs(**options) -
tests/modeltests/fixtures/models.py
diff -r fa1e8c79bda8 tests/modeltests/fixtures/models.py
a b 90 90 91 91 class Meta: 92 92 ordering = ('name',) 93 94 __test__ = {'API_TESTS': """95 >>> from django.core import management96 >>> from django.db.models import get_app97 98 # Reset the database representation of this app.99 # This will return the database to a clean initial state.100 >>> management.call_command('flush', verbosity=0, interactive=False)101 102 # Syncdb introduces 1 initial data object from initial_data.json.103 >>> Article.objects.all()104 [<Article: Python program becomes self aware>]105 106 # Load fixture 1. Single JSON file, with two objects.107 >>> management.call_command('loaddata', 'fixture1.json', verbosity=0)108 >>> Article.objects.all()109 [<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]110 111 # Dump the current contents of the database as a JSON fixture112 >>> management.call_command('dumpdata', 'fixtures', format='json')113 [{"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"}}]114 115 # Try just dumping the contents of fixtures.Category116 >>> management.call_command('dumpdata', 'fixtures.Category', format='json')117 [{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}]118 119 # ...and just fixtures.Article120 >>> management.call_command('dumpdata', 'fixtures.Article', format='json')121 [{"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"}}]122 123 # ...and both124 >>> management.call_command('dumpdata', 'fixtures.Category', 'fixtures.Article', format='json')125 [{"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"}}]126 127 # Specify a specific model twice128 >>> management.call_command('dumpdata', 'fixtures.Article', 'fixtures.Article', format='json')129 [{"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"}}]130 131 # Specify a dump that specifies Article both explicitly and implicitly132 >>> management.call_command('dumpdata', 'fixtures.Article', 'fixtures', format='json')133 [{"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"}}]134 135 # Same again, but specify in the reverse order136 >>> management.call_command('dumpdata', 'fixtures', 'fixtures.Article', format='json')137 [{"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"}}]138 139 # Specify one model from one application, and an entire other application.140 >>> management.call_command('dumpdata', 'fixtures.Category', 'sites', format='json')141 [{"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"}}]142 143 # Load fixture 2. JSON file imported by default. Overwrites some existing objects144 >>> management.call_command('loaddata', 'fixture2.json', verbosity=0)145 >>> Article.objects.all()146 [<Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]147 148 # Load fixture 3, XML format.149 >>> management.call_command('loaddata', 'fixture3.xml', verbosity=0)150 >>> Article.objects.all()151 [<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>]152 153 # Load fixture 6, JSON file with dynamic ContentType fields. Testing ManyToOne.154 >>> management.call_command('loaddata', 'fixture6.json', verbosity=0)155 >>> Tag.objects.all()156 [<Tag: <Article: Copyright is fine the way it is> tagged "copyright">, <Tag: <Article: Copyright is fine the way it is> tagged "law">]157 158 # Load fixture 7, XML file with dynamic ContentType fields. Testing ManyToOne.159 >>> management.call_command('loaddata', 'fixture7.xml', verbosity=0)160 >>> Tag.objects.all()161 [<Tag: <Article: Copyright is fine the way it is> tagged "copyright">, <Tag: <Article: Copyright is fine the way it is> tagged "legal">, <Tag: <Article: Django conquers world!> tagged "django">, <Tag: <Article: Django conquers world!> tagged "world domination">]162 163 # Load fixture 8, JSON file with dynamic Permission fields. Testing ManyToMany.164 >>> management.call_command('loaddata', 'fixture8.json', verbosity=0)165 >>> Visa.objects.all()166 [<Visa: Django Reinhardt Can add user, Can change user, Can delete user>, <Visa: Stephane Grappelli Can add user>, <Visa: Prince >]167 168 # Load fixture 9, XML file with dynamic Permission fields. Testing ManyToMany.169 >>> management.call_command('loaddata', 'fixture9.xml', verbosity=0)170 >>> Visa.objects.all()171 [<Visa: Django Reinhardt Can add user, Can change user, Can delete user>, <Visa: Stephane Grappelli Can add user, Can delete user>, <Visa: Artist formerly known as "Prince" Can change user>]172 173 >>> Book.objects.all()174 [<Book: Music for all ages by Artist formerly known as "Prince" and Django Reinhardt>]175 176 # Load a fixture that doesn't exist177 >>> management.call_command('loaddata', 'unknown.json', verbosity=0)178 179 # object list is unaffected180 >>> Article.objects.all()181 [<Article: XML identified as leading cause of cancer>, <Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker on TV is great!>, <Article: Python program becomes self aware>]182 183 # By default, you get raw keys on dumpdata184 >>> management.call_command('dumpdata', 'fixtures.book', format='json')185 [{"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [3, 1]}}]186 187 # But you can get natural keys if you ask for them and they are available188 >>> management.call_command('dumpdata', 'fixtures.book', format='json', use_natural_keys=True)189 [{"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [["Artist formerly known as \\"Prince\\""], ["Django Reinhardt"]]}}]190 191 # Dump the current contents of the database as a JSON fixture192 >>> management.call_command('dumpdata', 'fixtures', format='json', use_natural_keys=True)193 [{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 5, "model": "fixtures.article", "fields": {"headline": "XML identified as leading cause of cancer", "pub_date": "2006-06-16 16:00:00"}}, {"pk": 4, "model": "fixtures.article", "fields": {"headline": "Django conquers world!", "pub_date": "2006-06-16 15:00:00"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Copyright is fine the way it is", "pub_date": "2006-06-16 14:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker on TV is great!", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "legal", "tagged_id": 3}}, {"pk": 3, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "django", "tagged_id": 4}}, {"pk": 4, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "world domination", "tagged_id": 4}}, {"pk": 3, "model": "fixtures.person", "fields": {"name": "Artist formerly known as \\"Prince\\""}}, {"pk": 1, "model": "fixtures.person", "fields": {"name": "Django Reinhardt"}}, {"pk": 2, "model": "fixtures.person", "fields": {"name": "Stephane Grappelli"}}, {"pk": 1, "model": "fixtures.visa", "fields": {"person": ["Django Reinhardt"], "permissions": [["add_user", "auth", "user"], ["change_user", "auth", "user"], ["delete_user", "auth", "user"]]}}, {"pk": 2, "model": "fixtures.visa", "fields": {"person": ["Stephane Grappelli"], "permissions": [["add_user", "auth", "user"], ["delete_user", "auth", "user"]]}}, {"pk": 3, "model": "fixtures.visa", "fields": {"person": ["Artist formerly known as \\"Prince\\""], "permissions": [["change_user", "auth", "user"]]}}, {"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [["Artist formerly known as \\"Prince\\""], ["Django Reinhardt"]]}}]194 195 # Dump the current contents of the database as an XML fixture196 >>> management.call_command('dumpdata', 'fixtures', format='xml', use_natural_keys=True)197 <?xml version="1.0" encoding="utf-8"?>198 <django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="5" model="fixtures.article"><field type="CharField" name="headline">XML identified as leading cause of cancer</field><field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field></object><object pk="4" model="fixtures.article"><field type="CharField" name="headline">Django conquers world!</field><field type="DateTimeField" name="pub_date">2006-06-16 15:00:00</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Copyright is fine the way it is</field><field type="DateTimeField" name="pub_date">2006-06-16 14:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker on TV is great!</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">legal</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="3" model="fixtures.tag"><field type="CharField" name="name">django</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="4" model="fixtures.tag"><field type="CharField" name="name">world domination</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Artist formerly known as "Prince"</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object><object pk="1" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Django Reinhardt</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="2" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Stephane Grappelli</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="3" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Artist formerly known as "Prince"</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="1" model="fixtures.book"><field type="CharField" name="name">Music for all ages</field><field to="fixtures.person" name="authors" rel="ManyToManyRel"><object><natural>Artist formerly known as "Prince"</natural></object><object><natural>Django Reinhardt</natural></object></field></object></django-objects>199 200 """}201 202 # Database flushing does not work on MySQL with the default storage engine203 # because it requires transaction support.204 if settings.DATABASES[DEFAULT_DB_ALIAS]['ENGINE'] != 'django.db.backends.mysql':205 __test__['API_TESTS'] += \206 """207 # Reset the database representation of this app. This will delete all data.208 >>> management.call_command('flush', verbosity=0, interactive=False)209 >>> Article.objects.all()210 [<Article: Python program becomes self aware>]211 212 # Load fixture 1 again, using format discovery213 >>> management.call_command('loaddata', 'fixture1', verbosity=0)214 >>> Article.objects.all()215 [<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]216 217 # Try to load fixture 2 using format discovery; this will fail218 # because there are two fixture2's in the fixtures directory219 >>> management.call_command('loaddata', 'fixture2', verbosity=0) # doctest: +ELLIPSIS220 Multiple fixtures named 'fixture2' in '...fixtures'. Aborting.221 222 # object list is unaffected223 >>> Article.objects.all()224 [<Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]225 226 # Dump the current contents of the database as a JSON fixture227 >>> management.call_command('dumpdata', 'fixtures', format='json')228 [{"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"}}]229 230 # Load fixture 4 (compressed), using format discovery231 >>> management.call_command('loaddata', 'fixture4', verbosity=0)232 >>> Article.objects.all()233 [<Article: Django pets kitten>, <Article: Time to reform copyright>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]234 235 >>> management.call_command('flush', verbosity=0, interactive=False)236 237 # Load fixture 4 (compressed), using format specification238 >>> management.call_command('loaddata', 'fixture4.json', verbosity=0)239 >>> Article.objects.all()240 [<Article: Django pets kitten>, <Article: Python program becomes self aware>]241 242 >>> management.call_command('flush', verbosity=0, interactive=False)243 244 # Load fixture 5 (compressed), using format *and* compression specification245 >>> management.call_command('loaddata', 'fixture5.json.zip', verbosity=0)246 >>> Article.objects.all()247 [<Article: WoW subscribers now outnumber readers>, <Article: Python program becomes self aware>]248 249 >>> management.call_command('flush', verbosity=0, interactive=False)250 251 # Load fixture 5 (compressed), only compression specification252 >>> management.call_command('loaddata', 'fixture5.zip', verbosity=0)253 >>> Article.objects.all()254 [<Article: WoW subscribers now outnumber readers>, <Article: Python program becomes self aware>]255 256 >>> management.call_command('flush', verbosity=0, interactive=False)257 258 # Try to load fixture 5 using format and compression discovery; this will fail259 # because there are two fixture5's in the fixtures directory260 >>> management.call_command('loaddata', 'fixture5', verbosity=0) # doctest: +ELLIPSIS261 Multiple fixtures named 'fixture5' in '...fixtures'. Aborting.262 263 >>> management.call_command('flush', verbosity=0, interactive=False)264 265 # Load db fixtures 1 and 2. These will load using the 'default' database identifier implicitly266 >>> management.call_command('loaddata', 'db_fixture_1', verbosity=0)267 >>> management.call_command('loaddata', 'db_fixture_2', verbosity=0)268 >>> Article.objects.all()269 [<Article: Who needs more than one database?>, <Article: Who needs to use compressed data?>, <Article: Python program becomes self aware>]270 271 >>> management.call_command('flush', verbosity=0, interactive=False)272 273 # Load db fixtures 1 and 2. These will load using the 'default' database identifier explicitly274 >>> management.call_command('loaddata', 'db_fixture_1', verbosity=0, using='default')275 >>> management.call_command('loaddata', 'db_fixture_2', verbosity=0, using='default')276 >>> Article.objects.all()277 [<Article: Who needs more than one database?>, <Article: Who needs to use compressed data?>, <Article: Python program becomes self aware>]278 279 >>> management.call_command('flush', verbosity=0, interactive=False)280 281 # Try to load db fixture 3. This won't load because the database identifier doesn't match282 >>> management.call_command('loaddata', 'db_fixture_3', verbosity=0)283 >>> Article.objects.all()284 [<Article: Python program becomes self aware>]285 286 >>> management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default')287 >>> Article.objects.all()288 [<Article: Python program becomes self aware>]289 290 >>> management.call_command('flush', verbosity=0, interactive=False)291 292 # Load back in fixture 1, we need the articles from it293 >>> management.call_command('loaddata', 'fixture1', verbosity=0)294 295 # Try to load fixture 6 using format discovery296 >>> management.call_command('loaddata', 'fixture6', verbosity=0)297 >>> Tag.objects.all()298 [<Tag: <Article: Time to reform copyright> tagged "copyright">, <Tag: <Article: Time to reform copyright> tagged "law">]299 300 # Dump the current contents of the database as a JSON fixture301 >>> management.call_command('dumpdata', 'fixtures', format='json', use_natural_keys=True)302 [{"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"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "law", "tagged_id": 3}}, {"pk": 1, "model": "fixtures.person", "fields": {"name": "Django Reinhardt"}}, {"pk": 3, "model": "fixtures.person", "fields": {"name": "Prince"}}, {"pk": 2, "model": "fixtures.person", "fields": {"name": "Stephane Grappelli"}}]303 304 # Dump the current contents of the database as an XML fixture305 >>> management.call_command('dumpdata', 'fixtures', format='xml', use_natural_keys=True)306 <?xml version="1.0" encoding="utf-8"?>307 <django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Time to reform copyright</field><field type="DateTimeField" name="pub_date">2006-06-16 13:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker has no place on ESPN</field><field type="DateTimeField" name="pub_date">2006-06-16 12:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">law</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Prince</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object></django-objects>308 309 """310 311 from django.test import TestCase312 313 class SampleTestCase(TestCase):314 fixtures = ['fixture1.json', 'fixture2.json']315 316 def testClassFixtures(self):317 "Check that test case has installed 4 fixture objects"318 self.assertEqual(Article.objects.count(), 4)319 self.assertEquals(str(Article.objects.all()), "[<Article: Django conquers world!>, <Article: Copyright is fine the way it is>, <Article: Poker has no place on ESPN>, <Article: Python program becomes self aware>]") -
new file tests/modeltests/fixtures/tests.py
diff -r fa1e8c79bda8 tests/modeltests/fixtures/tests.py
- + 1 import StringIO 2 import sys 3 4 from django.test import TestCase, TransactionTestCase 5 from django.core import management 6 7 from models import Article, Blog, Book, Category, Person, Tag, Visa 8 9 class TestCaseFixtureLoadingTests(TestCase): 10 fixtures = ['fixture1.json', 'fixture2.json'] 11 12 def testClassFixtures(self): 13 "Check that test case has installed 4 fixture objects" 14 self.assertEqual(Article.objects.count(), 4) 15 self.assertQuerysetEqual(Article.objects.all(), [ 16 '<Article: Django conquers world!>', 17 '<Article: Copyright is fine the way it is>', 18 '<Article: Poker has no place on ESPN>', 19 '<Article: Python program becomes self aware>' 20 ]) 21 22 class FixtureLoadingTests(TestCase): 23 24 def _dumpdata_assert(self, args, output, format='json', natural_keys=False): 25 new_io = StringIO.StringIO() 26 management.call_command('dumpdata', *args, format=format, stdout=new_io, use_natural_keys=natural_keys) 27 command_output = new_io.getvalue().strip() 28 self.assertEqual(command_output, output) 29 30 def test_initial_data(self): 31 # Syncdb introduces 1 initial data object from initial_data.json. 32 self.assertQuerysetEqual(Article.objects.all(), [ 33 '<Article: Python program becomes self aware>' 34 ]) 35 36 def test_loading_and_dumping(self): 37 new_io = StringIO.StringIO() 38 39 # Load fixture 1. Single JSON file, with two objects. 40 management.call_command('loaddata', 'fixture1.json', verbosity=0, commit=False) 41 self.assertQuerysetEqual(Article.objects.all(), [ 42 '<Article: Time to reform copyright>', 43 '<Article: Poker has no place on ESPN>', 44 '<Article: Python program becomes self aware>' 45 ]) 46 47 # Dump the current contents of the database as a JSON fixture 48 self._dumpdata_assert(['fixtures'], '[{"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"}}]') 49 50 # Try just dumping the contents of fixtures.Category 51 self._dumpdata_assert(['fixtures.Category'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}]') 52 53 # ...and just fixtures.Article 54 self._dumpdata_assert(['fixtures.Article'], '[{"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"}}]') 55 56 # ...and both 57 self._dumpdata_assert(['fixtures.Category', 'fixtures.Article'], '[{"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"}}]') 58 59 # Specify a specific model twice 60 self._dumpdata_assert(['fixtures.Article', 'fixtures.Article'], '[{"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"}}]') 61 62 # Specify a dump that specifies Article both explicitly and implicitly 63 self._dumpdata_assert(['fixtures.Article', 'fixtures'], '[{"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"}}]') 64 65 # Same again, but specify in the reverse order 66 self._dumpdata_assert(['fixtures'], '[{"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"}}]') 67 68 # Specify one model from one application, and an entire other application. 69 self._dumpdata_assert(['fixtures.Category', 'sites'], '[{"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"}}]') 70 71 # Load fixture 2. JSON file imported by default. Overwrites some existing objects 72 management.call_command('loaddata', 'fixture2.json', verbosity=0, commit=False) 73 self.assertQuerysetEqual(Article.objects.all(), [ 74 '<Article: Django conquers world!>', 75 '<Article: Copyright is fine the way it is>', 76 '<Article: Poker has no place on ESPN>', 77 '<Article: Python program becomes self aware>' 78 ]) 79 80 # Load fixture 3, XML format. 81 management.call_command('loaddata', 'fixture3.xml', verbosity=0, commit=False) 82 self.assertQuerysetEqual(Article.objects.all(), [ 83 '<Article: XML identified as leading cause of cancer>', 84 '<Article: Django conquers world!>', 85 '<Article: Copyright is fine the way it is>', 86 '<Article: Poker on TV is great!>', 87 '<Article: Python program becomes self aware>' 88 ]) 89 90 # Load fixture 6, JSON file with dynamic ContentType fields. Testing ManyToOne. 91 management.call_command('loaddata', 'fixture6.json', verbosity=0, commit=False) 92 self.assertQuerysetEqual(Tag.objects.all(), [ 93 '<Tag: <Article: Copyright is fine the way it is> tagged "copyright">', 94 '<Tag: <Article: Copyright is fine the way it is> tagged "law">' 95 ]) 96 97 # Load fixture 7, XML file with dynamic ContentType fields. Testing ManyToOne. 98 management.call_command('loaddata', 'fixture7.xml', verbosity=0, commit=False) 99 self.assertQuerysetEqual(Tag.objects.all(), [ 100 '<Tag: <Article: Copyright is fine the way it is> tagged "copyright">', 101 '<Tag: <Article: Copyright is fine the way it is> tagged "legal">', 102 '<Tag: <Article: Django conquers world!> tagged "django">', 103 '<Tag: <Article: Django conquers world!> tagged "world domination">' 104 ]) 105 106 # Load fixture 8, JSON file with dynamic Permission fields. Testing ManyToMany. 107 management.call_command('loaddata', 'fixture8.json', verbosity=0, commit=False) 108 self.assertQuerysetEqual(Visa.objects.all(), [ 109 '<Visa: Django Reinhardt Can add user, Can change user, Can delete user>', 110 '<Visa: Stephane Grappelli Can add user>', 111 '<Visa: Prince >' 112 ]) 113 114 # Load fixture 9, XML file with dynamic Permission fields. Testing ManyToMany. 115 management.call_command('loaddata', 'fixture9.xml', verbosity=0, commit=False) 116 self.assertQuerysetEqual(Visa.objects.all(), [ 117 '<Visa: Django Reinhardt Can add user, Can change user, Can delete user>', 118 '<Visa: Stephane Grappelli Can add user, Can delete user>', 119 '<Visa: Artist formerly known as "Prince" Can change user>' 120 ]) 121 122 self.assertQuerysetEqual(Book.objects.all(), [ 123 '<Book: Music for all ages by Artist formerly known as "Prince" and Django Reinhardt>' 124 ]) 125 126 # Load a fixture that doesn't exist 127 management.call_command('loaddata', 'unknown.json', verbosity=0, commit=False) 128 129 # object list is unaffected 130 self.assertQuerysetEqual(Article.objects.all(), [ 131 '<Article: XML identified as leading cause of cancer>', 132 '<Article: Django conquers world!>', 133 '<Article: Copyright is fine the way it is>', 134 '<Article: Poker on TV is great!>', 135 '<Article: Python program becomes self aware>' 136 ]) 137 138 # By default, you get raw keys on dumpdata 139 self._dumpdata_assert(['fixtures.book'], '[{"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [3, 1]}}]') 140 141 # But you can get natural keys if you ask for them and they are available 142 self._dumpdata_assert(['fixtures.book'], '[{"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [["Artist formerly known as \\"Prince\\""], ["Django Reinhardt"]]}}]', natural_keys=True) 143 144 # Dump the current contents of the database as a JSON fixture 145 self._dumpdata_assert(['fixtures'], '[{"pk": 1, "model": "fixtures.category", "fields": {"description": "Latest news stories", "title": "News Stories"}}, {"pk": 5, "model": "fixtures.article", "fields": {"headline": "XML identified as leading cause of cancer", "pub_date": "2006-06-16 16:00:00"}}, {"pk": 4, "model": "fixtures.article", "fields": {"headline": "Django conquers world!", "pub_date": "2006-06-16 15:00:00"}}, {"pk": 3, "model": "fixtures.article", "fields": {"headline": "Copyright is fine the way it is", "pub_date": "2006-06-16 14:00:00"}}, {"pk": 2, "model": "fixtures.article", "fields": {"headline": "Poker on TV is great!", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.article", "fields": {"headline": "Python program becomes self aware", "pub_date": "2006-06-16 11:00:00"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "legal", "tagged_id": 3}}, {"pk": 3, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "django", "tagged_id": 4}}, {"pk": 4, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "world domination", "tagged_id": 4}}, {"pk": 3, "model": "fixtures.person", "fields": {"name": "Artist formerly known as \\"Prince\\""}}, {"pk": 1, "model": "fixtures.person", "fields": {"name": "Django Reinhardt"}}, {"pk": 2, "model": "fixtures.person", "fields": {"name": "Stephane Grappelli"}}, {"pk": 1, "model": "fixtures.visa", "fields": {"person": ["Django Reinhardt"], "permissions": [["add_user", "auth", "user"], ["change_user", "auth", "user"], ["delete_user", "auth", "user"]]}}, {"pk": 2, "model": "fixtures.visa", "fields": {"person": ["Stephane Grappelli"], "permissions": [["add_user", "auth", "user"], ["delete_user", "auth", "user"]]}}, {"pk": 3, "model": "fixtures.visa", "fields": {"person": ["Artist formerly known as \\"Prince\\""], "permissions": [["change_user", "auth", "user"]]}}, {"pk": 1, "model": "fixtures.book", "fields": {"name": "Music for all ages", "authors": [["Artist formerly known as \\"Prince\\""], ["Django Reinhardt"]]}}]', natural_keys=True) 146 147 # Dump the current contents of the database as an XML fixture 148 self._dumpdata_assert(['fixtures'], """<?xml version="1.0" encoding="utf-8"?> 149 <django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="5" model="fixtures.article"><field type="CharField" name="headline">XML identified as leading cause of cancer</field><field type="DateTimeField" name="pub_date">2006-06-16 16:00:00</field></object><object pk="4" model="fixtures.article"><field type="CharField" name="headline">Django conquers world!</field><field type="DateTimeField" name="pub_date">2006-06-16 15:00:00</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Copyright is fine the way it is</field><field type="DateTimeField" name="pub_date">2006-06-16 14:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker on TV is great!</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">legal</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="3" model="fixtures.tag"><field type="CharField" name="name">django</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="4" model="fixtures.tag"><field type="CharField" name="name">world domination</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">4</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Artist formerly known as "Prince"</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object><object pk="1" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Django Reinhardt</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="2" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Stephane Grappelli</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>add_user</natural><natural>auth</natural><natural>user</natural></object><object><natural>delete_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="3" model="fixtures.visa"><field to="fixtures.person" name="person" rel="ManyToOneRel"><natural>Artist formerly known as "Prince"</natural></field><field to="auth.permission" name="permissions" rel="ManyToManyRel"><object><natural>change_user</natural><natural>auth</natural><natural>user</natural></object></field></object><object pk="1" model="fixtures.book"><field type="CharField" name="name">Music for all ages</field><field to="fixtures.person" name="authors" rel="ManyToManyRel"><object><natural>Artist formerly known as "Prince"</natural></object><object><natural>Django Reinhardt</natural></object></field></object></django-objects>""", format='xml', natural_keys=True) 150 151 def test_compress_format_loading(self): 152 # Load fixture 4 (compressed), using format specification 153 management.call_command('loaddata', 'fixture4.json', verbosity=0, commit=False) 154 self.assertQuerysetEqual(Article.objects.all(), [ 155 '<Article: Django pets kitten>', 156 '<Article: Python program becomes self aware>' 157 ]) 158 159 def test_compressed_specified_loading(self): 160 # Load fixture 5 (compressed), using format *and* compression specification 161 management.call_command('loaddata', 'fixture5.json.zip', verbosity=0, commit=False) 162 self.assertQuerysetEqual(Article.objects.all(), [ 163 '<Article: WoW subscribers now outnumber readers>', 164 '<Article: Python program becomes self aware>' 165 ]) 166 167 def test_compressed_loading(self): 168 # Load fixture 5 (compressed), only compression specification 169 management.call_command('loaddata', 'fixture5.zip', verbosity=0, commit=False) 170 self.assertQuerysetEqual(Article.objects.all(), [ 171 '<Article: WoW subscribers now outnumber readers>', 172 '<Article: Python program becomes self aware>' 173 ]) 174 175 def test_ambiguous_compressed_fixture(self): 176 # The name "fixture5" is ambigous, so loading it will raise an error 177 new_io = StringIO.StringIO() 178 management.call_command('loaddata', 'fixture5', verbosity=0, stdout=new_io, commit=False) 179 output = new_io.getvalue().strip().split('\n') 180 self.assertEqual(len(output), 1) 181 self.assertTrue(output[0].startswith("Multiple fixtures named 'fixture5'")) 182 183 def test_db_loading(self): 184 # Load db fixtures 1 and 2. These will load using the 'default' database identifier implicitly 185 management.call_command('loaddata', 'db_fixture_1', verbosity=0, commit=False) 186 management.call_command('loaddata', 'db_fixture_2', verbosity=0, commit=False) 187 self.assertQuerysetEqual(Article.objects.all(), [ 188 '<Article: Who needs more than one database?>', 189 '<Article: Who needs to use compressed data?>', 190 '<Article: Python program becomes self aware>' 191 ]) 192 193 def test_loading_using(self): 194 # Load db fixtures 1 and 2. These will load using the 'default' database identifier explicitly 195 management.call_command('loaddata', 'db_fixture_1', verbosity=0, using='default', commit=False) 196 management.call_command('loaddata', 'db_fixture_2', verbosity=0, using='default', commit=False) 197 self.assertQuerysetEqual(Article.objects.all(), [ 198 '<Article: Who needs more than one database?>', 199 '<Article: Who needs to use compressed data?>', 200 '<Article: Python program becomes self aware>' 201 ]) 202 203 def test_unmatched_identifier_loading(self): 204 # Try to load db fixture 3. This won't load because the database identifier doesn't match 205 management.call_command('loaddata', 'db_fixture_3', verbosity=0, commit=False) 206 self.assertQuerysetEqual(Article.objects.all(), [ 207 '<Article: Python program becomes self aware>' 208 ]) 209 210 management.call_command('loaddata', 'db_fixture_3', verbosity=0, using='default', commit=False) 211 self.assertQuerysetEqual(Article.objects.all(), [ 212 '<Article: Python program becomes self aware>' 213 ]) 214 215 def test_output_formats(self): 216 # Load back in fixture 1, we need the articles from it 217 management.call_command('loaddata', 'fixture1', verbosity=0, commit=False) 218 219 # Try to load fixture 6 using format discovery 220 management.call_command('loaddata', 'fixture6', verbosity=0, commit=False) 221 self.assertQuerysetEqual(Tag.objects.all(), [ 222 '<Tag: <Article: Time to reform copyright> tagged "copyright">', 223 '<Tag: <Article: Time to reform copyright> tagged "law">' 224 ]) 225 226 # Dump the current contents of the database as a JSON fixture 227 self._dumpdata_assert(['fixtures'], '[{"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"}}, {"pk": 1, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "copyright", "tagged_id": 3}}, {"pk": 2, "model": "fixtures.tag", "fields": {"tagged_type": ["fixtures", "article"], "name": "law", "tagged_id": 3}}, {"pk": 1, "model": "fixtures.person", "fields": {"name": "Django Reinhardt"}}, {"pk": 3, "model": "fixtures.person", "fields": {"name": "Prince"}}, {"pk": 2, "model": "fixtures.person", "fields": {"name": "Stephane Grappelli"}}]', natural_keys=True) 228 229 # Dump the current contents of the database as an XML fixture 230 self._dumpdata_assert(['fixtures'], """<?xml version="1.0" encoding="utf-8"?> 231 <django-objects version="1.0"><object pk="1" model="fixtures.category"><field type="CharField" name="title">News Stories</field><field type="TextField" name="description">Latest news stories</field></object><object pk="3" model="fixtures.article"><field type="CharField" name="headline">Time to reform copyright</field><field type="DateTimeField" name="pub_date">2006-06-16 13:00:00</field></object><object pk="2" model="fixtures.article"><field type="CharField" name="headline">Poker has no place on ESPN</field><field type="DateTimeField" name="pub_date">2006-06-16 12:00:00</field></object><object pk="1" model="fixtures.article"><field type="CharField" name="headline">Python program becomes self aware</field><field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field></object><object pk="1" model="fixtures.tag"><field type="CharField" name="name">copyright</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="2" model="fixtures.tag"><field type="CharField" name="name">law</field><field to="contenttypes.contenttype" name="tagged_type" rel="ManyToOneRel"><natural>fixtures</natural><natural>article</natural></field><field type="PositiveIntegerField" name="tagged_id">3</field></object><object pk="1" model="fixtures.person"><field type="CharField" name="name">Django Reinhardt</field></object><object pk="3" model="fixtures.person"><field type="CharField" name="name">Prince</field></object><object pk="2" model="fixtures.person"><field type="CharField" name="name">Stephane Grappelli</field></object></django-objects>""", format='xml', natural_keys=True) 232 233 class FixtureTransactionTests(TransactionTestCase): 234 235 def _dumpdata_assert(self, args, output, format='json'): 236 new_io = StringIO.StringIO() 237 management.call_command('dumpdata', *args, format=format, stdout=new_io) 238 command_output = new_io.getvalue().strip() 239 self.assertEqual(command_output, output) 240 241 def test_format_discovery(self): 242 # Load fixture 1 again, using format discovery 243 management.call_command('loaddata', 'fixture1', verbosity=0, commit=False) 244 self.assertQuerysetEqual(Article.objects.all(), [ 245 '<Article: Time to reform copyright>', 246 '<Article: Poker has no place on ESPN>', 247 '<Article: Python program becomes self aware>' 248 ]) 249 250 # Try to load fixture 2 using format discovery; this will fail 251 # because there are two fixture2's in the fixtures directory 252 new_io = StringIO.StringIO() 253 management.call_command('loaddata', 'fixture2', verbosity=0, stdout=new_io) 254 output = new_io.getvalue().strip().split('\n') 255 self.assertEqual(len(output), 1) 256 self.assertTrue(output[0].startswith("Multiple fixtures named 'fixture2'")) 257 258 # object list is unaffected 259 self.assertQuerysetEqual(Article.objects.all(), [ 260 '<Article: Time to reform copyright>', 261 '<Article: Poker has no place on ESPN>', 262 '<Article: Python program becomes self aware>' 263 ]) 264 265 # Dump the current contents of the database as a JSON fixture 266 self._dumpdata_assert(['fixtures'], '[{"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"}}]') 267 268 # Load fixture 4 (compressed), using format discovery 269 management.call_command('loaddata', 'fixture4', verbosity=0, commit=False) 270 self.assertQuerysetEqual(Article.objects.all(), [ 271 '<Article: Django pets kitten>', 272 '<Article: Time to reform copyright>', 273 '<Article: Poker has no place on ESPN>', 274 '<Article: Python program becomes self aware>' 275 ])