Wagtail: StructBlockのdumpdataコマンドが壊れています

作成日 2017年01月14日  ·  3コメント  ·  ソース: wagtail/wagtail

問題の概要

モデルでStructBlockを使用する場合

再現する手順

このモデルをエクスポートしようとすると、コマンドがクラッシュすることがわかりました。

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'

ただ行う:

python3 manage.py dumpdata --traceback

そして例外が発生します:

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

技術的な詳細

  • Pythonバージョン:Python 3.5.1
  • Djangoバージョン:Django(1.10.4)
  • セキレイバージョン:セキレイ(1.8)

最も参考になるコメント

こんにちは@soar

次の手順では、新規インストールでこれを再現できません。

  • コマンドライン:

    wagtail start dumpdatatest
    cd dumpdatatest
    ./manage.py migrate
    ./manage.py createsuperuser
    
  • 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'),
        ]
    
  • コマンドライン:

    ./manage.py makemigrations  # (use '' as default)
    ./manage.py runserver
    
  • 管理者にログインし、ホームページを編集し、画像ブロックを追加し、公開します

  • ./manage.py dumpdata --traceback実行します

これにより、期待どおりにダンプが生成されます。

StreamField定義には元々通常のImageChooserBlockが含まれていたため、エラーが発生していると思われますが、現在のStructBlock定義に変更しました。 StreamField定義を変更しても、既存のページデータは自動的に更新されないため、既存のページには引き続き誤ったデータ型が含まれます。

全てのコメント3件

こんにちは@soar

次の手順では、新規インストールでこれを再現できません。

  • コマンドライン:

    wagtail start dumpdatatest
    cd dumpdatatest
    ./manage.py migrate
    ./manage.py createsuperuser
    
  • 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'),
        ]
    
  • コマンドライン:

    ./manage.py makemigrations  # (use '' as default)
    ./manage.py runserver
    
  • 管理者にログインし、ホームページを編集し、画像ブロックを追加し、公開します

  • ./manage.py dumpdata --traceback実行します

これにより、期待どおりにダンプが生成されます。

StreamField定義には元々通常のImageChooserBlockが含まれていたため、エラーが発生していると思われますが、現在のStructBlock定義に変更しました。 StreamField定義を変更しても、既存のページデータは自動的に更新されないため、既存のページには引き続き誤ったデータ型が含まれます。

あなたは正しいです、これは私の間違いでした。 お時間をいただきごめんなさい@gasman

@gasmanでは、最も簡単な解決策はフィールドの名前を変更することでしょうか? 自動的に更新されないので、または古い値が存在するページから古い値を更新または削除する方法はありますか?

このページは役に立ちましたか?
0 / 5 - 0 評価