Beispiel #1
0
    def test_blank_false_is_implied_by_default(self):
        # passing a block list
        field = StreamField([("paragraph", blocks.CharBlock())],
                            use_json_field=self.use_json_field)
        self.assertTrue(field.stream_block.required)
        with self.assertRaises(StreamBlockValidationError):
            field.stream_block.clean([])

        class MyStreamBlock(blocks.StreamBlock):
            paragraph = blocks.CharBlock()

            class Meta:
                required = False

        # passing a block instance
        field = StreamField(MyStreamBlock(),
                            use_json_field=self.use_json_field)
        self.assertTrue(field.stream_block.required)
        with self.assertRaises(StreamBlockValidationError):
            field.stream_block.clean([])

        field = StreamField(MyStreamBlock(required=False),
                            use_json_field=self.use_json_field)
        self.assertTrue(field.stream_block.required)
        with self.assertRaises(StreamBlockValidationError):
            field.stream_block.clean([])

        # passing a block class
        field = StreamField(MyStreamBlock, use_json_field=self.use_json_field)
        self.assertTrue(field.stream_block.required)
        with self.assertRaises(StreamBlockValidationError):
            field.stream_block.clean([])
Beispiel #2
0
    def test_blank_field_is_not_required(self):
        # passing a block list
        field = StreamField(
            [("paragraph", blocks.CharBlock())],
            blank=True,
            use_json_field=self.use_json_field,
        )
        self.assertFalse(field.stream_block.required)
        field.stream_block.clean([])  # no validation error on empty stream

        class MyStreamBlock(blocks.StreamBlock):
            paragraph = blocks.CharBlock()

            class Meta:
                required = True

        # passing a block instance
        field = StreamField(MyStreamBlock(),
                            blank=True,
                            use_json_field=self.use_json_field)
        self.assertFalse(field.stream_block.required)
        field.stream_block.clean([])  # no validation error on empty stream

        field = StreamField(MyStreamBlock(required=True),
                            blank=True,
                            use_json_field=self.use_json_field)
        self.assertFalse(field.stream_block.required)
        field.stream_block.clean([])  # no validation error on empty stream

        # passing a block class
        field = StreamField(MyStreamBlock,
                            blank=True,
                            use_json_field=self.use_json_field)
        self.assertFalse(field.stream_block.required)
        field.stream_block.clean([])  # no validation error on empty stream
Beispiel #3
0
    def test_internal_type(self):
        text = StreamField([("paragraph", blocks.CharBlock())],
                           use_json_field=False)
        json = StreamField([("paragraph", blocks.CharBlock())],
                           use_json_field=True)

        self.assertEqual(text.get_internal_type(), "TextField")
        self.assertEqual(json.get_internal_type(), "JSONField")
Beispiel #4
0
class ResourcesPage(Page):
    resources = StreamField(
        [
            (
                "resource",
                blocks.StreamBlock(
                    [
                        ("resource_name", blocks.CharBlock()),
                        ("information", blocks.RichTextBlock()),
                        (
                            "structured_info_block",
                            blocks.StreamBlock(
                                [
                                    ("heading", blocks.CharBlock()),
                                    ("body", blocks.RichTextBlock()),
                                ]
                            ),
                        ),
                    ]
                ),
            )
        ],
        use_json_field=True,
    )
    content_panels = Page.content_panels + [
        FieldPanel("resources"),
    ]
Beispiel #5
0
 class DeprecatedStreamModel(models.Model):
     body = StreamField(
         [
             ("heading", blocks.CharBlock()),
             ("rich text", blocks.RichTextBlock()),
         ],
     )
Beispiel #6
0
class DocumentPage(Page):
    date_published = models.DateField("Last Updated", blank=True, null=True)
    body = StreamField(
        [(
            "section",
            blocks.StreamBlock([
                ("header", CharBlock()),
                ("text", blocks.RichTextBlock()),
                ("quote", BlockQuoteBlock()),
                (
                    "subsection",
                    blocks.StreamBlock([
                        ("header", CharBlock()),
                        ("text", blocks.TextBlock()),
                        (
                            "subsubsection",
                            blocks.StreamBlock([
                                ("header", CharBlock()),
                                ("text", blocks.TextBlock()),
                            ]),
                        ),
                    ]),
                ),
            ]),
        )],
        null=True,
        blank=True,
        use_json_field=True,
    )

    content_panels = Page.content_panels + [
        FieldPanel("date_published"),
        FieldPanel("body"),
    ]
Beispiel #7
0
class StreamPage(Page):
    body = StreamField(
        [
            ("text", CharBlock()),
            ("rich_text", RichTextBlock()),
            ("image", ExtendedImageChooserBlock()),
            (
                "product",
                StructBlock([
                    ("name", CharBlock()),
                    ("price", CharBlock()),
                ]),
            ),
            ("raw_html", RawHTMLBlock()),
            (
                "books",
                StreamBlock([
                    ("title", CharBlock()),
                    ("author", CharBlock()),
                ]),
            ),
        ],
        use_json_field=False,
    )

    api_fields = ("body", )

    content_panels = [
        FieldPanel("title"),
        FieldPanel("body"),
    ]

    preview_modes = []
Beispiel #8
0
 class InvalidStreamModel(models.Model):
     body = StreamField(
         [
             ("heading", blocks.CharBlock()),
             ("rich text", blocks.RichTextBlock()),
         ],
         use_json_field=self.use_json_field,
     )
Beispiel #9
0
class DefaultRichBlockFieldPage(Page):
    body = StreamField(
        [
            ("rich_text", RichTextBlock()),
        ],
        use_json_field=False,
    )

    content_panels = Page.content_panels + [FieldPanel("body")]
Beispiel #10
0
class JSONStreamModel(models.Model):
    body = StreamField(
        [
            ("text", CharBlock()),
            ("rich_text", RichTextBlock()),
            ("image", ImageChooserBlock()),
        ],
        use_json_field=True,
    )
Beispiel #11
0
    def test_streamfield_count_argument_precedence(self):
        class TestStreamBlock(blocks.StreamBlock):
            heading = blocks.CharBlock()
            paragraph = blocks.RichTextBlock()

            class Meta:
                min_num = 2
                max_num = 5
                block_counts = {"heading": {"max_num": 1}}

        # args being picked up from the class definition
        field = StreamField(TestStreamBlock,
                            use_json_field=self.use_json_field)
        self.assertEqual(field.stream_block.meta.min_num, 2)
        self.assertEqual(field.stream_block.meta.max_num, 5)
        self.assertEqual(
            field.stream_block.meta.block_counts["heading"]["max_num"], 1)

        # args being overridden by StreamField
        field = StreamField(
            TestStreamBlock,
            min_num=3,
            max_num=6,
            block_counts={"heading": {
                "max_num": 2
            }},
            use_json_field=self.use_json_field,
        )
        self.assertEqual(field.stream_block.meta.min_num, 3)
        self.assertEqual(field.stream_block.meta.max_num, 6)
        self.assertEqual(
            field.stream_block.meta.block_counts["heading"]["max_num"], 2)

        # passing None from StreamField should cancel limits set at the block level
        field = StreamField(
            TestStreamBlock,
            min_num=None,
            max_num=None,
            block_counts=None,
            use_json_field=self.use_json_field,
        )
        self.assertIsNone(field.stream_block.meta.min_num)
        self.assertIsNone(field.stream_block.meta.max_num)
        self.assertIsNone(field.stream_block.meta.block_counts)
Beispiel #12
0
class DeadlyStreamPage(Page):
    body = StreamField(
        [
            ("title", DeadlyCharBlock()),
        ],
        use_json_field=False,
    )
    content_panels = Page.content_panels + [
        FieldPanel("body"),
    ]
Beispiel #13
0
class JSONMinMaxCountStreamModel(models.Model):
    body = StreamField(
        [
            ("text", CharBlock()),
            ("rich_text", RichTextBlock()),
            ("image", ImageChooserBlock()),
        ],
        min_num=2,
        max_num=5,
        use_json_field=True,
    )
Beispiel #14
0
class CustomRichBlockFieldPage(Page):
    body = StreamField(
        [
            ("rich_text", RichTextBlock(editor="custom")),
        ],
        use_json_field=False,
    )

    content_panels = [
        FieldPanel("title", classname="full title"),
        FieldPanel("body"),
    ]
Beispiel #15
0
class InlineStreamPageSection(Orderable):
    page = ParentalKey("tests.InlineStreamPage",
                       related_name="sections",
                       on_delete=models.CASCADE)
    body = StreamField(
        [
            ("text", CharBlock()),
            ("rich_text", RichTextBlock()),
            ("image", ImageChooserBlock()),
        ],
        use_json_field=False,
    )
    panels = [FieldPanel("body")]
Beispiel #16
0
class DefaultStreamPage(Page):
    body = StreamField(
        [
            ("text", CharBlock()),
            ("rich_text", RichTextBlock()),
            ("image", ImageChooserBlock()),
        ],
        default="",
        use_json_field=False,
    )

    content_panels = [
        FieldPanel("title"),
        FieldPanel("body"),
    ]
Beispiel #17
0
class InfoPage(Page):
    body = RichTextField(blank=True)
    additional_content = StreamField(
        [("embed", blocks.RawHTMLBlock())],
        null=True,
        blank=True,
        use_json_field=True,
    )

    search_fields = Page.search_fields + [
        index.SearchField("body"),
    ]

    content_panels = Page.content_panels + [
        FieldPanel("body", classname="full"),
        FieldPanel("additional_content"),
    ]
Beispiel #18
0
class JSONBlockCountsStreamModel(models.Model):
    body = StreamField(
        [
            ("text", CharBlock()),
            ("rich_text", RichTextBlock()),
            ("image", ImageChooserBlock()),
        ],
        block_counts={
            "text": {
                "min_num": 1
            },
            "rich_text": {
                "max_num": 1
            },
            "image": {
                "min_num": 1,
                "max_num": 1
            },
        },
        use_json_field=True,
    )
Beispiel #19
0
class StreamPage(Page):
    body = StreamField([
        ("map", GoogleMapsBlock()),
        ("map_leaflet", LeafletBlock()),
        (
            "map_struct",
            blocks.StructBlock(
                [
                    ("address", GeoAddressBlock(required=True)),
                    ("map", GoogleMapsBlock(address_field="address")),
                ],
                icon="user",
            ),
        ),
        (
            "map_struct_with_deprecated_geopanel",
            blocks.StructBlock(
                [
                    ("address", blocks.CharBlock(required=True)),
                    ("map", GeoBlock(address_field="address")),
                ],
                icon="user",
            ),
        ),
        (
            "map_struct_leaflet",
            blocks.StructBlock(
                [
                    (
                        "address",
                        GeoAddressBlock(required=True,
                                        geocoder=geocoders.MAPBOX),
                    ),
                    ("map", LeafletBlock(address_field="address")),
                ],
                icon="user",
            ),
        ),
        (
            "map_struct_with_zoom",
            blocks.StructBlock(
                [
                    ("address", GeoAddressBlock(required=True)),
                    ("zoom", GeoZoomBlock(required=False)),
                    (
                        "map",
                        GoogleMapsBlock(address_field="address",
                                        zoom_field="zoom"),
                    ),
                ],
                icon="user",
            ),
        ),
        (
            "map_struct_leaflet_with_zoom",
            blocks.StructBlock(
                [
                    ("address", GeoAddressBlock(required=True)),
                    ("zoom", GeoZoomBlock(required=False)),
                    (
                        "map",
                        LeafletBlock(address_field="address",
                                     zoom_field="zoom"),
                    ),
                ],
                icon="user",
            ),
        ),
    ])

    content_panels = Page.content_panels + [
        StreamFieldPanel("body"),
    ]
Beispiel #20
0
class PageWithStreamField(Page):
    body = StreamField(BaseStreamBlock(), verbose_name="Page body", blank=True)
Beispiel #21
0
class BlogPage(HeadlessPreviewMixin, Page):
    date = models.DateField("Post date")
    advert = models.ForeignKey(
        "home.Advert",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    hero_image = models.ForeignKey(
        "images.CustomImage",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    book_file = models.ForeignKey(
        document_model_string,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    featured_media = models.ForeignKey(
        "wagtailmedia.Media",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    author = models.ForeignKey(
        AuthorPage, null=True, blank=True, on_delete=models.SET_NULL, related_name="+"
    )
    body = StreamField(StreamFieldBlock())
    tags = ClusterTaggableManager(through=BlogPageTag, blank=True)

    content_panels = Page.content_panels + [
        FieldPanel("date"),
        ImageChooserPanel("hero_image"),
        StreamFieldPanel("body"),
        FieldPanel("tags"),
        InlinePanel("related_links", label="Related links"),
        InlinePanel("authors", label="Authors"),
        FieldPanel("author"),
        SnippetChooserPanel("advert"),
        DocumentChooserPanel("book_file"),
        MediaChooserPanel("featured_media"),
    ]

    @property
    def copy(self):
        return self

    def paginated_authors(self, info, **kwargs):
        return resolve_paginated_queryset(self.authors, info, **kwargs)

    graphql_fields = [
        GraphQLString("date", required=True),
        GraphQLStreamfield("body"),
        GraphQLTag("tags"),
        GraphQLCollection(
            GraphQLForeignKey,
            "related_links",
            "home.blogpagerelatedlink",
            required=True,
            item_required=True,
        ),
        GraphQLCollection(GraphQLString, "related_urls", source="related_links.url"),
        GraphQLCollection(GraphQLString, "authors", source="authors.person.name"),
        GraphQLCollection(
            GraphQLForeignKey,
            "paginated_authors",
            "home.Author",
            is_paginated_queryset=True,
        ),
        GraphQLSnippet("advert", "home.Advert"),
        GraphQLImage("hero_image"),
        GraphQLDocument("book_file"),
        GraphQLMedia("featured_media"),
        GraphQLForeignKey("copy", "home.BlogPage"),
        GraphQLPage("author"),
    ]
Beispiel #22
0
class NewsPage(Page):
    main_story_image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )
    main_story_heading = models.CharField(max_length=500,
                                          null=True,
                                          blank=True)
    main_story_copy = RichTextField(blank=True)
    action_network_href = models.URLField(blank=True, null=True)
    related_stories = StreamField(
        [("related_story", RelatedStoryBlock())],
        null=True,
        blank=True,
        collapsed=False,
        default=upcoming_events_as_related_stories,
        use_json_field=True,
    )

    parent_page_type = ["news.NewsIndexPage"]  # appname.ModelName
    search_fields = Page.search_fields + [
        index.SearchField("main_story_copy"),
    ]

    content_panels = Page.content_panels + [
        FieldPanel("main_story_image", ),
        FieldPanel("main_story_heading"),
        FieldPanel("main_story_copy", classname="full"),
        FieldPanel("related_stories"),
    ]

    def save(self, *args, **kwargs):
        if self.action_network_href:
            email.edit(
                self.action_network_href,
                {
                    "subject":
                    self.title,
                    "body":
                    render_block_to_string("news/news_page.html",
                                           "content",
                                           context={"page": self}),
                    "from":
                    "STL DSA",
                    "reply_to":
                    "*****@*****.**",
                },
                settings.ACTIONNETWORK_API_KEYS["main"],
            )
        else:
            response = email.create(
                self.title,
                # main_story_html + "".join(related_stories_html),
                render_block_to_string("news/news_page.html",
                                       "content",
                                       context={"page": self}),
                "STL DSA",
                "*****@*****.**",
                settings.ACTIONNETWORK_API_KEYS["main"],
            )
            action_network_href = response.json()["_links"]["self"]["href"]
            self.action_network_href = action_network_href

        if self.go_live_at and self.go_live_at > timezone.now():
            polling.poll(
                lambda: requests.get(
                    self.action_network_href,
                    headers={
                        "OSDI-API-Token": settings.ACTIONNETWORK_API_KEYS[
                            "main"]
                    },
                ).json().get("total_targeted", 0) > 0,
                step=1,
                timeout=10,
                step_function=lambda step: step + 2,
            )
            email.schedule(
                f"{self.action_network_href}/schedule",
                self.go_live_at,
                settings.ACTIONNETWORK_API_KEYS["main"],
            )
        super().save(*args, **kwargs)  # Call the "real" save() method.
Beispiel #23
0
class AddedStreamFieldWithEmptyListDefaultPage(Page):
    body = StreamField([("title", CharBlock())],
                       default=[],
                       use_json_field=False)
Beispiel #24
0
 def test_use_json_field_warning(self):
     message = "StreamField must explicitly set use_json_field argument to True/False instead of None."
     with self.assertWarnsMessage(RemovedInWagtail50Warning, message):
         StreamField([("paragraph", blocks.CharBlock())])
Beispiel #25
0
class TableBlockStreamPage(Page):
    table = StreamField([("table", TableBlock())], use_json_field=False)

    content_panels = [FieldPanel("table")]
Beispiel #26
0
class GeoStreamPage(Page):
    body = StreamField([
        ("map", GoogleMapsBlock()),
        ("map_with_leaflet", LeafletBlock()),
        (
            "map_struct",
            blocks.StructBlock(
                [
                    ("address", GeoAddressBlock(required=True)),
                    ("map", GoogleMapsBlock(address_field="address")),
                ],
                icon="user",
            ),
        ),
        (
            "map_struct_with_deprecated_geopanel",
            blocks.StructBlock(
                [
                    ("address", blocks.CharBlock(required=True)),
                    ("map", GeoBlock(address_field="address")),
                ],
                icon="user",
            ),
        ),
        (
            "map_struct_with_leaflet",
            blocks.StructBlock(
                [
                    ("address", GeoAddressBlock(required=True)),
                    ("map", LeafletBlock(address_field="address")),
                ],
                icon="user",
            ),
        ),
        (
            "map_struct_with_zoom",
            blocks.StructBlock(
                [
                    ("address", GeoAddressBlock(required=True)),
                    ("zoom", GeoZoomBlock(required=False)),
                    (
                        "map",
                        GoogleMapsBlock(address_field="address",
                                        zoom_field="zoom"),
                    ),
                ],
                icon="user",
            ),
        ),
        (
            "map_struct_leaflet_with_zoom",
            blocks.StructBlock(
                [
                    ("address", GeoAddressBlock(required=True)),
                    ("zoom", GeoZoomBlock(required=False)),
                    (
                        "map",
                        LeafletBlock(address_field="address",
                                     zoom_field="zoom"),
                    ),
                ],
                icon="user",
            ),
        ),
    ])

    content_panels = Page.content_panels + [
        StreamFieldPanel("body"),
    ]

    def get_context(self, request):
        data = super(GeoStreamPage, self).get_context(request)
        return data