Ticket #13636: 13636-r13318.diff

File 13636-r13318.diff, 59.7 KB (added by russellm, 5 years ago)

Updated fix, mostly formatting changes (this time with the missing file)

  • django/core/management/base.py

    diff -r fa1e8c79bda8 django/core/management/base.py
    a b  
    213213                sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
    214214                sys.exit(1)
    215215        try:
     216            self.stdout = options.get('stdout', sys.stdout)
     217            self.stderr = options.get('stderr', sys.stderr)
    216218            if self.requires_model_validation:
    217219                self.validate()
    218220            output = self.handle(*args, **options)
     
    223225                    from django.db import connections, DEFAULT_DB_ALIAS
    224226                    connection = connections[options.get('database', DEFAULT_DB_ALIAS)]
    225227                    if connection.ops.start_transaction_sql():
    226                         print self.style.SQL_KEYWORD(connection.ops.start_transaction_sql())
    227                 print output
     228                        self.stdout.write(self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()))
     229                self.stdout.write(output)
    228230                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')
    230232        except CommandError, e:
    231             sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
     233            self.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
    232234            sys.exit(1)
    233235
    234236    def validate(self, app=None, display_num_errors=False):
     
    250252            error_text = s.read()
    251253            raise CommandError("One or more models did not validate:\n%s" % error_text)
    252254        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 ''))
    254256
    255257    def handle(self, *args, **options):
    256258        """
  • django/core/management/commands/loaddata.py

    diff -r fa1e8c79bda8 django/core/management/commands/loaddata.py
    a b  
    112112
    113113            if formats:
    114114                if verbosity > 1:
    115                     print "Loading '%s' fixtures..." % fixture_name
     115                    self.stdout.write("Loading '%s' fixtures...\n" % fixture_name)
    116116            else:
    117117                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" %
    119119                        (fixture_name, format)))
    120120                transaction.rollback(using=using)
    121121                transaction.leave_transaction_management(using=using)
     
    128128
    129129            for fixture_dir in fixture_dirs:
    130130                if verbosity > 1:
    131                     print "Checking %s for fixtures..." % humanize(fixture_dir)
     131                    self.stdout.write("Checking %s for fixtures...\n" % humanize(fixture_dir))
    132132
    133133                label_found = False
    134134                for combo in product([using, None], formats, compression_formats):
     
    141141                    )
    142142
    143143                    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))
    146146                    full_path = os.path.join(fixture_dir, file_name)
    147147                    open_method = compression_types[compression_format]
    148148                    try:
    149149                        fixture = open_method(full_path, 'r')
    150150                        if label_found:
    151151                            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))))
    154154                            transaction.rollback(using=using)
    155155                            transaction.leave_transaction_management(using=using)
    156156                            return
     
    158158                            fixture_count += 1
    159159                            objects_in_fixture = 0
    160160                            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)))
    163163                            try:
    164164                                objects = serializers.deserialize(format, fixture, using=using)
    165165                                for obj in objects:
     
    190190                            # error was encountered during fixture loading.
    191191                            if objects_in_fixture == 0:
    192192                                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" %
    194194                                        (fixture_name)))
    195195                                transaction.rollback(using=using)
    196196                                transaction.leave_transaction_management(using=using)
     
    198198
    199199                    except Exception, e:
    200200                        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)))
    203203
    204204        # If we found even one object in a fixture, we need to reset the
    205205        # database sequences.
     
    207207            sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
    208208            if sequence_sql:
    209209                if verbosity > 1:
    210                     print "Resetting sequences"
     210                    self.stdout.write("Resetting sequences\n")
    211211                for line in sequence_sql:
    212212                    cursor.execute(line)
    213213
     
    217217
    218218        if object_count == 0:
    219219            if verbosity > 0:
    220                 print "No fixtures found."
     220                self.stdout.write("No fixtures found.\n")
    221221        else:
    222222            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))
    224224
    225225        # Close the DB connection. This is required as a workaround for an
    226226        # 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  
    88
    99Applications can register their own actions with ``manage.py``. For example,
    1010you 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`` 
     11distributing. In this document, we will be building a custom ``closepoll``
    1212command for the ``polls`` application from the
    1313:ref:`tutorial<intro-tutorial01>`.
    1414
     
    6262                poll.opened = False
    6363                poll.save()
    6464
    65                 print 'Successfully closed poll "%s"' % poll_id
     65                self.stdout.write('Successfully closed poll "%s"\n' % poll_id)
    6666
    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
     74The new custom command can be called using ``python manage.py closepoll
    6875<poll_id>``.
    6976
    7077The ``handle()`` method takes zero or more ``poll_ids`` and sets ``poll.opened``
     
    9198            )
    9299        # ...
    93100
    94 In addition to being able to add custom command line options, all 
    95 :ref:`management commands<ref-django-admin>` can accept some 
     101In addition to being able to add custom command line options, all
     102:ref:`management commands<ref-django-admin>` can accept some
    96103default options such as :djadminopt:`--verbosity` and :djadminopt:`--traceback`.
    97104
    98105Command objects
     
    113120Attributes
    114121----------
    115122
    116 All attributes can be set in your derived class and can be used in 
     123All attributes can be set in your derived class and can be used in
    117124:class:`BaseCommand`'s :ref:`subclasses<ref-basecommand-subclasses>`.
    118125
    119126.. attribute:: BaseCommand.args
     
    133140.. attribute:: BaseCommand.help
    134141
    135142  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
    137144  ``python manage.py help <command>``.
    138145
    139146.. attribute:: BaseCommand.option_list
     
    230237A command which takes no arguments on the command line.
    231238
    232239Rather 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
    234241overridden to ensure no arguments are passed to the command.
    235242
    236243.. method:: NoArgsCommand.handle_noargs(**options)
  • tests/modeltests/fixtures/models.py

    diff -r fa1e8c79bda8 tests/modeltests/fixtures/models.py
    a b  
    9090
    9191    class Meta:
    9292        ordering = ('name',)
    93 
    94 __test__ = {'API_TESTS': """
    95 >>> from django.core import management
    96 >>> from django.db.models import get_app
    97 
    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 fixture
    112 >>> 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.Category
    116 >>> 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.Article
    120 >>> 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 both
    124 >>> 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 twice
    128 >>> 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 implicitly
    132 >>> 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 order
    136 >>> 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 objects
    144 >>> 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 exist
    177 >>> management.call_command('loaddata', 'unknown.json', verbosity=0)
    178 
    179 # object list is unaffected
    180 >>> 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 dumpdata
    184 >>> 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 available
    188 >>> 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 fixture
    192 >>> 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 fixture
    196 >>> 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 engine
    203 # 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 discovery
    213 >>> 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 fail
    218 # because there are two fixture2's in the fixtures directory
    219 >>> management.call_command('loaddata', 'fixture2', verbosity=0) # doctest: +ELLIPSIS
    220 Multiple fixtures named 'fixture2' in '...fixtures'. Aborting.
    221 
    222 # object list is unaffected
    223 >>> 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 fixture
    227 >>> 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 discovery
    231 >>> 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 specification
    238 >>> 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 specification
    245 >>> 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 specification
    252 >>> 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 fail
    259 # because there are two fixture5's in the fixtures directory
    260 >>> management.call_command('loaddata', 'fixture5', verbosity=0) # doctest: +ELLIPSIS
    261 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 implicitly
    266 >>> 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 explicitly
    274 >>> 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 match
    282 >>> 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 it
    293 >>> management.call_command('loaddata', 'fixture1', verbosity=0)
    294 
    295 # Try to load fixture 6 using format discovery
    296 >>> 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 fixture
    301 >>> 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 fixture
    305 >>> 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 TestCase
    312 
    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
    - +  
     1import StringIO
     2import sys
     3
     4from django.test import TestCase, TransactionTestCase
     5from django.core import management
     6
     7from models import Article, Blog, Book, Category, Person, Tag, Visa
     8
     9class 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
     22class 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
     233class 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        ])
Back to Top