从页面slug返回Wagtail API的所有字段

时间:2018-06-08 16:54:55

标签: django wagtail

我正在创建一个VueJS前端应用程序,它使用Wagtail CMS作为后端,并通过Wagtail APIV2连接。我遇到的问题是通过页面slug检索页面信息。此查询不会返回其他字段,而按页面类型和页面ID排序将是。

博客模型看起来像这样(我为了简洁起见了一些方法:

class BlogPage(Page):
    intro = RichTextField(blank=True)
    body = StreamField(blocks.CMSStreamBlock(), blank=True)
    tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
    date = models.DateField("Post date")
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        default='',
        on_delete=models.SET_NULL,
        related_name='author_data',
        null=True,
        blank=True,
        limit_choices_to=limit_author_choices
    )
    feed_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    class Meta:
        verbose_name = "Blog and Updates Page"

    content_panels = [
        FieldPanel('title', classname="full title"),
        FieldPanel('date'),
        FieldPanel('author'),
        ImageChooserPanel('feed_image'),
        FieldPanel('tags'),
        FieldPanel('intro', classname="full"),
        StreamFieldPanel('body'),
    ]

    api_fields = [
        APIField('feed_img', serializer=ImageRenditionField('width-800', source='feed_image')),
        APIField('intro'),
        APIField('body'),
        APIField('tags'),
        APIField('date'),
        APIField('author')
    ]

如果我查询http://localhost:8000/api/v2/pages/?type=cms.BlogPage&fields= *它返回:

{
    "meta": {
        "total_count": 4
    },
    "items": [
        {
            "id": 8,
            "meta": {
                "type": "cms.BlogPage",
                "detail_url": "http://localhost:8000/api/v2/pages/8/",
                "html_url": "http://localhost:8000/en/blog/first-blog-post/",
                "slug": "first-blog-post",
                "show_in_menus": false,
                "seo_title": "",
                "search_description": "",
                "first_published_at": "2017-10-18T22:54:14.709694Z"
            },
            "title": "First blog post",
            "feed_img": {
                "url": "/media/images/DSC02705.width-800.jpg",
                "width": 800,
                "height": 534
            },
            "intro": "<p>Praesent placerat in eros sit amet gravida. Curabitur nec semper ligula, sit amet egestas sapien. Nullam feugiat non mi vitae egestas. Morbi hendrerit mauris mauris, et tempor eros euismod hendrerit. Integer tempor lacus nulla, eget posuere ex dignissim quis. Donec laoreet tempor suscipit. Etiam ut purus eget turpis commodo aliquam. Donec sed maximus diam, non venenatis arcu. Sed mollis laoreet euismod.</p>",
            "body": [
                {
                    "type": "paragraph",
                    "value": "<p>A bunch more text in here.</p><p>Ut sit amet nisl condimentum, convallis neque eu, fringilla leo. Quisque tincidunt sed quam vel pulvinar. Maecenas vehicula pharetra volutpat. Integer velit mi, scelerisque quis lacus nec, molestie pharetra nisi. Vivamus efficitur magna vel justo lacinia tincidunt. Nam at mi accumsan, sagittis risus sed, iaculis leo. Nullam faucibus lorem a consequat varius. Etiam consectetur metus dui, et maximus turpis volutpat at. Donec vitae blandit nisi. Phasellus commodo vehicula ante vel accumsan. Fusce nec lorem urna. Pellentesque eget dapibus nibh, in ultrices felis. Curabitur felis erat, luctus eu maximus eu, pretium id lorem.</p><p>Nunc consequat, velit non consectetur laoreet, elit nisl finibus diam, id ultrices nunc quam imperdiet mi. Integer vel mi ac quam viverra pellentesque eu eu ante. Cras at est id augue hendrerit pretium ac non sem. Donec quis auctor sem, vel commodo nisi. Mauris ac tincidunt diam. Sed vel erat rhoncus, euismod nisl sit amet, tincidunt arcu. Nam a auctor lorem. Vestibulum in mauris lacus.</p><p>Duis posuere enim odio, vel lacinia nulla condimentum non. Nulla vitae pulvinar neque, sed ultricies est. Nullam fringilla id nibh imperdiet euismod. Pellentesque mauris turpis, tincidunt id commodo in, dictum a tortor. Vestibulum sit amet mollis lacus. Aenean laoreet venenatis orci. Sed nec aliquam ante. Cras congue eu urna eget faucibus. Ut lobortis convallis dictum. Donec aliquet massa sed tortor molestie, ac vestibulum eros imperdiet. Sed eget elit est. Nulla convallis, lorem ac dignissim aliquam, nisi turpis sollicitudin ipsum, vel dictum urna turpis eu orci. Morbi varius massa nisi, nec egestas massa imperdiet tempor. Morbi semper enim non condimentum bibendum. Mauris pulvinar hendrerit tincidunt.</p>",
                    "id": "bebd35d4-a2ad-4b82-baf1-305e817ec55e"
                }
            ],
            "tags": [
                "Tag1",
                "Tag2"
            ],
            "date": "2017-10-18",
            "author": {
                "id": 2,
                "meta": {
                    "type": "users.User"
                }
            }
        },
        {
            "id": 9,
    .....

如果我查询http://localhost:8000/api/v2/pages/8/,则返回所有字段。 但是,如果我查询http://localhost:8000/api/v2/pages/?slug=second-blog-post&fields= *

我得到了

{
    "meta": {
        "total_count": 1
    },
    "items": [
        {
            "id": 9,
            "meta": {
                "type": "cms.BlogPage",
                "detail_url": "http://localhost:8000/api/v2/pages/9/",
                "html_url": "http://localhost:8000/en/blog/second-blog-post/",
                "slug": "second-blog-post",
                "show_in_menus": false,
                "seo_title": "",
                "search_description": "",
                "first_published_at": "2017-10-19T00:07:22.887487Z"
            },
            "title": "Second blog post"
        }
    ]
}

如果我查询http://localhost:8000/api/v2/pages/?slug=second-blog-post&fields=body,我会

{
    "message": "unknown fields: body"
}

所以看来我无法从slug查找中检索所有记录字段。这意味着从我需要的slug查询中填充页面: 1.通过slug查找页面 2.记录页面ID 3.再次拨打电话以按页面ID检索字段。

这似乎是漫长的过程。我错过了什么吗?

1 个答案:

答案 0 :(得分:1)

Wagtail Slack提出并回答了这个问题。这是@gasman的答案

  

我认为这个问题是通过slug&#39;机制仍然最终使用API​​端点来获取页面列表而不是单个页面,而且不会在查询集上调用specific() - 这意味着只有核心页面字段可用。

     

通过一些重新管道,您可以自定义PagesAPIEndpoint类来调用specific() - Wagtail管理员有一个内部API,可以执行类似的操作(以及一堆其他自定义): https://github.com/wagtail/wagtail/blob/master/wagtail/admin/api/endpoints.py

     

或者,你可以使用新的&#39;找到&#39;而不是通过slug(因为同一个slug可能存在于多个不同的父母下面而有点脆弱)。在Wagtail 2.1中添加了端点:http://docs.wagtail.io/en/v2.1/advanced_topics/api/v2/usage.html#finding-pages-by-html-path

     

不幸的是,在目前的形式中,它仍然会涉及到API的冗余往返,因为它适用于重定向,但它至少会为您节省一些代码......