2016-11-15 1 views
1

У меня есть страница с одним телом StreamField и пользовательский блок с именем HeadingBlock:добавить/изменить значение блоков в трясогузка streamfield из оболочки

class HeadingBlock(blocks.StructBlock): 
    heading = blocks.CharBlock() 
    cssid = blocks.CharBlock() 
    ... 

class CustomPage(Page): 
    ... 
    body = StreamField([ 
     ('heading', HeadingBlock()), 
    ... 

Мне нужно добавить новый charblock к товарной позиции атрибут HeadingBlock, но с использованием оболочки :

>>> from custom.models import CustomPage 
>>> c = CustomPage.objects.all()[0] 
>>> c.body[0].heading.value = "hello world" ??? this does not work 

Любой может помочь? большое спасибо!

EDIT: Я упростил HeadingBlock, удаляя ListBlock и попробовал:

>>> c.body[0].value 
StructValue([('heading', u'hi'), ('cssid', u'man')]) 
>>> type(c.body[0].value) 
<class 'wagtail.wagtailcore.blocks.struct_block.StructValue'> 
>>> from wagtail.wagtailcore.blocks.struct_block import StructValue 
>>> c.body[0].value = StructValue([('heading', u'hello'), ('cssid', u'world')]) 
>>> c.save() 

, но когда я иду в интерфейсе администратора, эти поля пустыми. Я пробовал:

>>> c.body[0].block.child_blocks 
OrderedDict([('heading', <wagtail.wagtailcore.blocks.field_block.CharBlock object at 0x7f4c2aaf9790>), ('cssid', <wagtail.wagtailcore.blocks.field_block.CharBlock object at 0x7f4c2aaf9a90>)]) 
>>> c.body[0].block.child_blocks['heading'] 
<wagtail.wagtailcore.blocks.field_block.CharBlock object at 0x7f4c2aaf9790> 
>>> c.body[0].block.child_blocks['heading'].value 
Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
AttributeError: 'CharBlock' object has no attribute 'value' 

Ничего не случится, я не думаю, что это так сложно: - |

+0

Вы сохраняете объект? Попробуйте 'c.save()' в конце – kristian

+0

. Я пытаюсь упростить вопрос –

ответ

3

Вывод StructValue([('heading', u'hi'), ('cssid', u'man')]) немного вводит в заблуждение - для создания собственного StructValue вам необходимо передать соответствующий объект StructBlock. Другая проблема, с которой вы можете столкнуться, заключается в том, что значение StreamField не предназначено для обновления «на месте», как в c.body[0].value (хотя это значение may change in a future Wagtail release).

Рекомендуемый способ обновления StreamField - построить новое значение, состоящее из списка (block_type, value) кортежей. При использовании этого подхода, то StreamField будет заботиться о преобразовании значения в правильный тип - это для StructBlock, вы можете просто передать в Словаре, а не строить свой собственный StructValue:

c.body = [ 
    ('heading', {'heading': 'hi', 'cssid': 'man'}) 
] 

Если есть существующие данные поле, которое вы хотите сохранить, более полный фрагмент кода может выглядеть примерно так:

new_body = [] 
for block_type, value in c.body: 
    if block_type == 'heading': 
     new_body.append(
      ('heading', {'heading': 'hello world', 'cssid': value['cssid']}) 
     ) 
    else: 
     new_body.append((block_type, value)) 

c.body = new_body 
+0

спасибо, он работает! –

Смежные вопросы