When StructBlock is used in models
I've found that command is crashed when it tries to export this model:
from wagtail.wagtailcore import blocks
from wagtail.wagtailimages.blocks import ImageChooserBlock
class ImageBlock(blocks.StructBlock):
image = ImageChooserBlock()
description = blocks.CharBlock()
class Meta:
icon = 'image'
template = 'image.html'
Just do:
python3 manage.py dumpdata --traceback
And exception occurs:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "C:\Soft\python\venv\lib\site-packages\django\core\management\__init__.py", line 367, in execute_from_command_line
utility.execute()
File "C:\Soft\python\venv\lib\site-packages\django\core\management\__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "C:\Soft\python\venv\lib\site-packages\django\core\management\base.py", line 294, in run_from_argv
self.execute(*args, **cmd_options)
File "C:\Soft\python\venv\lib\site-packages\django\core\management\base.py", line 345, in execute
output = self.handle(*args, **options)
File "C:\Soft\python\venv\lib\site-packages\django\core\management\commands\dumpdata.py", line 200, in handle
object_count=object_count,
File "C:\Soft\python\venv\lib\site-packages\django\core\serializers\__init__.py", line 129, in serialize
s.serialize(queryset, **options)
File "C:\Soft\python\venv\lib\site-packages\django\core\serializers\base.py", line 88, in serialize
self.handle_field(obj, field)
File "C:\Soft\python\venv\lib\site-packages\django\core\serializers\python.py", line 54, in handle_field
self._current[field.name] = field.value_to_string(obj)
File "C:\Soft\python\venv\lib\site-packages\wagtail\wagtailcore\fields.py", line 123, in value_to_string
return self.get_prep_value(value)
File "C:\Soft\python\venv\lib\site-packages\wagtail\wagtailcore\fields.py", line 107, in get_prep_value
return json.dumps(self.stream_block.get_prep_value(value), cls=DjangoJSONEncoder)
File "C:\Soft\python\venv\lib\site-packages\wagtail\wagtailcore\blocks\stream_block.py", line 211, in get_prep_value
for child in value # child is a BoundBlock instance
File "C:\Soft\python\venv\lib\site-packages\wagtail\wagtailcore\blocks\stream_block.py", line 210, in <listcomp>
{'type': child.block.name, 'value': child.block.get_prep_value(child.value)}
File "C:\Python35-32\lib\_collections_abc.py", line 815, in __iter__
v = self[i]
File "C:\Soft\python\venv\lib\site-packages\wagtail\wagtailcore\blocks\stream_block.py", line 324, in __getitem__
value = child_block.to_python(raw_value['value'])
File "C:\Soft\python\venv\lib\site-packages\wagtail\wagtailcore\blocks\struct_block.py", line 131, in to_python
for name, child_block in self.child_blocks.items()
File "C:\Soft\python\venv\lib\site-packages\wagtail\wagtailcore\blocks\struct_block.py", line 131, in <listcomp>
for name, child_block in self.child_blocks.items()
TypeError: argument of type 'int' is not iterable
Hi @soar,
I'm unable to reproduce this on a fresh installation, with this procedure:
On the command line:
wagtail start dumpdatatest
cd dumpdatatest
./manage.py migrate
./manage.py createsuperuser
Edit home/models.py:
from __future__ import absolute_import, unicode_literals
from django.db import models
from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore import blocks
from wagtail.wagtailcore.fields import StreamField
from wagtail.wagtailimages.blocks import ImageChooserBlock
from wagtail.wagtailadmin.edit_handlers import FieldPanel, StreamFieldPanel
class ImageBlock(blocks.StructBlock):
image = ImageChooserBlock()
description = blocks.CharBlock()
class Meta:
icon = 'image'
template = 'image.html'
class HomePage(Page):
body = StreamField([
('image', ImageBlock()),
])
content_panels = [
FieldPanel('title'),
StreamFieldPanel('body'),
]
On the command line:
./manage.py makemigrations # (use '' as default)
./manage.py runserver
log in to admin, edit homepage, add an image block, publish
./manage.py dumpdata --tracebackThis produces the dump as expected.
I suspect the error is occurring because your StreamField definition originally had an ordinary ImageChooserBlock, but you changed it to the current StructBlock definition. Changing the StreamField definition does not automatically update the existing page data, so any existing pages will still have the incorrect data type in them.
You are right, this was my mistake. Sorry for your time @gasman
@gasman So would the easiest solution be to rename the field? Since it doesn't automatically update or is there a way to update or remove the old values from pages they exist on?
Most helpful comment
Hi @soar,
I'm unable to reproduce this on a fresh installation, with this procedure:
On the command line:
Edit home/models.py:
On the command line:
log in to admin, edit homepage, add an image block, publish
./manage.py dumpdata --tracebackThis produces the dump as expected.
I suspect the error is occurring because your StreamField definition originally had an ordinary
ImageChooserBlock, but you changed it to the currentStructBlockdefinition. Changing the StreamField definition does not automatically update the existing page data, so any existing pages will still have the incorrect data type in them.