2017-12-11 14 views
0

페이지 탐색을 위해 사이드 바 탐색 기능이있는 긴 스크롤 페이지를 만들어야합니다. 즉, 각 표제에는 ID가 있습니다. 스트림 필드에서 사용자가 중복 ID를 넣지 않았는지 확인해야합니까?스트림 필드에 중복이 없음을 확인하십시오.

편집 :
제목이 같은 정의됩니다

class HeadingOneBlock(blocks.StructBlock): 
    id = blocks.RegexBlock(regex=r'^\S*$', help_text='No spaces or special characters') 
    heading = blocks.CharBlock() 

    class Meta: 
     template = 'base/heading_one.html' 
     icon = 'title' 
     label = 'h1' 

그리고 페이지 다음 '몸'수준에서 검증 할 수있는 방법이

class LongScrollPage(Page): 
    banner_text = RichTextField() 
    description = RichTextField() 
    body = StreamField([ 
     ('heading1', HeadingOneBlock()), 
     ('heading2', HeadingTwoBlock()), 
     ('paragraph', blocks.RichTextBlock(features=['bold', 'italic', 'ol', 'ul', 'link', 'image', 'hr'])), 
     ('collapsible_panel', CollapsiblePanelBlock()), 
     ('table', TableBlock(template='base/tables.html')), 
    ], blank=True, null=True) 

    content_panels = Page.content_panels + [ 
     FieldPanel('banner_text'), 
     FieldPanel('description'), 
     StreamFieldPanel('body'), 
    ] 

있습니까? 블록 수준에서 유효성을 검사 할 수 있지만 고유 ID를 확인하려면 어떻게해야합니까?

+0

를 사용하여 BakeryDemo, 할미새 1.13에서이 작업을 테스트했습니다. –

답변

0

이 문제를 해결하는 한 가지 방법은 StreamField의 맞춤 validators입니다.

Django Form Validation에 대한 자세한 내용은 정보를 참조하십시오.

또한 유효성 검사기에 표시되는 value[StreamValue](https://github.com/wagtail/wagtail/blob/master/wagtail/core/blocks/stream_block.py#L324)의 인스턴스이며 튜플 목록을 포함하는 stream_data 속성을 갖습니다. 각 튜플의 첫 번째 항목은 블록에 부여한 레이블입니다 (예 : heading1, heading2, 단락). 두 번째 항목은 StructValue 인스턴스이며 각 하위 블록 값은 아래 예제에서 hence data[1].get('id') 키를 통해 액세스 할 수 있습니다.

검사기 코드 (또한 models.py 파일에있을 수 있습니다) :

from django.core.exceptions import ValidationError 
from wagtail.core.blocks import StreamBlockValidationError # plus all blocks imported here 


def validate_ids_in_headings(value): 
    # value.stream_data is a list of tuples 
    # first item in each tuple is the label (eg. 'heading1' or 'paragraph') 
    # second item in each tuple is a StructValue which is like an ordered dict 
    items = [ 
     data[1].get('id') 
     for data in value.stream_data 
     if 'heading' in data[0] 
    ] 
    if len(set(items)) != len(items): 
     # sets can only be unique so - the items are are not unique 
     # must raise special StreamBlockValidationError error like this 
     raise StreamBlockValidationError(
      non_block_errors=ValidationError(
       'All headings must have unique ID values: %(value)s', 
       code='invalid', 
       params={'value': items}, 
      ) 
     ) 
    # if valid, do nothing 

개정 모델 코드 :

# using one HeadingBlock class here as you can define template/label within the StreamField 
class HeadingBlock(StructBlock): 
    id = RegexBlock(regex=r'^\S*$', help_text='No spaces or special characters') 
    heading = CharBlock() 
    class Meta: 
     icon = 'title' 


body = StreamField([ 
    ('heading1', HeadingBlock(label='h1', template='base/heading_one.html')), # note: label/template set here 
    ('heading2', HeadingBlock(label='h2', template='base/heading_two.html')), # note: label/template set here 
    ('paragraph', RichTextBlock(features=['bold', 'italic', 'ol', 'ul', 'link', 'image', 'hr'])), 
    ('collapsible_panel', CollapsiblePanelBlock()), 
    ('table', TableBlock(template='base/tables.html')), 
# validators set here, must be within a list - even if one item, removed null=True as not needed 
], blank=True, validators=[validate_ids_in_headings]) 

이 사용자에게 표시 오류가 발생합니다.

불행히도 이것은 (오류 표시기와 함께) 탭을 강조 표시하지 않지만 'Body'블록의 시작 부분에 특정 오류 텍스트가있는 오류를 표시합니다 (Issue 4122 참조).

난 당신이 예를 들어,이 질문에 지금까지 사용하고있는 코드를 좀 더 정보를 넣어 주 시겠어요 파이썬 3

+0

감사합니다. – jeffreyb