Search code examples
pythondjangowagtaildjango-testing

Django tests have started failing after adding Wagtail objects


I'm using regular Django tests for my Django models, using

./manage.py test non_wagtail_app_name

but all of sudden (and after adding some Wagtail models), I can't run them:

Creating test database for alias 'default'...
Traceback (most recent call last):
  File "./manage.py", line 12, in <module>
    execute_from_command_line(sys.argv)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/__init__.py", line 364, in execute_from_command_line
    utility.execute()
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/commands/test.py", line 29, in run_from_argv
    super(Command, self).run_from_argv(argv)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/commands/test.py", line 62, in handle
    failures = test_runner.run_tests(test_labels)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/test/runner.py", line 601, in run_tests
    old_config = self.setup_databases()
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/test/runner.py", line 546, in setup_databases
    self.parallel, **kwargs
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/test/utils.py", line 187, in setup_databases
    serialize=connection.settings_dict.get('TEST', {}).get('SERIALIZE', True),
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/backends/base/creation.py", line 69, in create_test_db
    run_syncdb=True,
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/__init__.py", line 131, in call_command
    return command.execute(*args, **defaults)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/core/management/commands/migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/migrations/executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/migrations/executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/migrations/executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/migrations/migration.py", line 129, in apply
    operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/migrations/operations/fields.py", line 88, in database_forwards
    field,
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 431, in add_field
    definition, params = self.column_sql(model, field, include_default=True)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 171, in column_sql
    default_value = self.effective_default(field)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/backends/base/schema.py", line 245, in effective_default
    default = field.get_db_prep_save(default, self.connection)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 770, in get_db_prep_save
    prepared=False)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 762, in get_db_prep_value
    value = self.get_prep_value(value)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/wagtail/core/fields.py", line 106, in get_prep_value
    return json.dumps(self.stream_block.get_prep_value(value), cls=DjangoJSONEncoder)
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/wagtail/core/blocks/stream_block.py", line 252, in get_prep_value
    for child in value  # child is a StreamChild instance
  File "/home/fleon/development/virmyasb/lib/python3.6/site-packages/wagtail/core/blocks/stream_block.py", line 252, in <listcomp>
    for child in value  # child is a StreamChild instance
AttributeError: 'str' object has no attribute 'block'

The traceback seems to come from the Wagtail part of my project (my Wagtail models use StreamFields and BlockFields), so it seems I'm missing something (putting fixtures for my Wagtail objects), but I'm clueless where to start from (I haven't setup Wagtail tests yet - yes, I know, I should). The app I want to test doesn't use anything from Wagtail.

The only thing that works is pg_dumping my Postgres database, edit the database name in the generated file, importing it into test_postgres and passing the -k switch to manage.py test, so it's quite obvious I need to prefill the Wagtail tables. However, using fixtures in the Django models tests doesn't fix the problem...


Solution

  • This is failing while running migrations. Digging through the stack trace, my best guess is that:

    • this is a migration that adds a StreamField to an existing page model, as a required (null=False) field
    • there is an existing instance of that page model (most likely, it's HomePage, as the standard Wagtail project template creates one of those as part of the initial migrations), and so it needs to be populated with a default value
    • the default value that you specified when creating the migration is a non-empty string, which isn't a valid value for a StreamField

    If so, the fix is to edit the offending migration and change the default value on the StreamField to an empty string.