Wagtail通用库实现和OneToOneField

时间:2017-12-24 11:02:56

标签: wagtail

http://docs.wagtail.io/en/v1.13.1/getting_started/tutorial.html

wagtail getting_started教程介绍了一个博客库功能,实现如下:

class BlogPage(Page):
    ...

class BlogPageGalleryImage(Orderable)
    page = ParentalKey(BlogPage, related_name='gallery_images')
    image = ...

这种方式有效,但BlogPageGalleryImage与BlogPage模型相结合。我的目的是制作一个可以嵌入任何模型(页面)的通用图库模型。这个想法是使用中间的Gallery模型:

class BlogPage(Page):
    gallery = models.OneToOneField(Gallery, on_delete=models.SET_NULL, null=True)
    ...

class Gallery(Page):
    pass

class GalleryImage(Orderable):
    gallery = ParentalKey(Gallery, related_name='images')

然后在代码中,我们可以通过blog.gallery.images获取图片。

我的问题是如何在编辑博客页面对象时使用wagtail管理界面来内联创建/编辑图库对象(OneToOneField)。

1 个答案:

答案 0 :(得分:2)

实现此目的的一种方法是通过更为通用的页面 - 图像连接关系,将其与页面模型相关联,而不是与特定的BlogPage模型相关联。

这意味着任何页面都可以包含图库图片,您只需要通过InlinePanel将该字段公开给内容面板。

您还可以创建一个Mixin类,以便在不重写它们的情况下提供一些有用的方法。

以下是一个例子:

from django.db import models

from wagtail.admin.edit_handlers import InlinePanel
from wagtail.core.models import Orderable, Page
from wagtail.images.edit_handlers import ImageChooserPanel

class ImageGalleryRelationship(Orderable, models.Model):
    """ Relationship between any `Page` and `Image` for an image gallery."""
    page = ParentalKey(Page, related_name='gallery_page')
    image = models.ForeignKey('wagtailimages.Image', related_name='gallery_image')
    panels = [ImageChooserPanel('image')]


class PageGalleryMixin():
    def gallery_images(self):
        images = [g.image for g in self.gallery_page.all()]
        return images

class BlogPage(Page, PageGalleryMixin):
    # all page fields, gallery does not need to be defined here
    content_panels = Page.content_panels + [
        InlinePanel('gallery_page', label='Image Gallery'),
        #...
    ]

注意:这不是OneToOne连接,InlinePanel需要ParentalKey关系。这个解决方案中没有真正的“图库”模型只是一组可订购的关系。