Wagtail 通用画廊实现和 OneToOneField
Wagtail generic gallery implementation and OneToOneField
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 模型相结合。我的目的是制作一个可以嵌入任何模型(页面)的通用画廊模型。这个想法是使用中间画廊模型:
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 管理界面一起工作,以便在编辑博客页面对象时内联 create/edit 图库对象 (OneToOneField)。
一种方法是通过更通用的页面图像连接关系,将其与页面模型相关联,而不是特定的 BlogPage 模型。
这意味着任何页面都可以有图库图片,您只需要通过 InlinePanel
.
将该字段公开给内容面板
您还可以创建一个 Mixin class 来提供一些有用的方法,而无需每次都重写它们。
这是一个例子:
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关系。此解决方案中没有真正的 'Gallery' 模型,只有一组可排序关系。
在一般应用程序(或任何地方)中,models.py
class PageGalleryImage(Orderable):
page = ParentalKey(Page,
on_delete=models.CASCADE,
related_name='image_gallery')
image = models.ForeignKey('wagtailimages.Image',
on_delete=models.CASCADE,
related_name='page_gallery_image')
caption = models.CharField(blank=True, max_length=250)
panels = [
ImageChooserPanel('image'),
FieldPanel('caption'),
]
博客等其他应用,models.py:
class BlogPage(Page):
content_panels = Page.content_panels + [
...
InlinePanel('image_gallery', label="Gallery images"),
]
这提供了一个应用程序 = 一个图库。
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 模型相结合。我的目的是制作一个可以嵌入任何模型(页面)的通用画廊模型。这个想法是使用中间画廊模型:
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 管理界面一起工作,以便在编辑博客页面对象时内联 create/edit 图库对象 (OneToOneField)。
一种方法是通过更通用的页面图像连接关系,将其与页面模型相关联,而不是特定的 BlogPage 模型。
这意味着任何页面都可以有图库图片,您只需要通过 InlinePanel
.
您还可以创建一个 Mixin class 来提供一些有用的方法,而无需每次都重写它们。
这是一个例子:
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关系。此解决方案中没有真正的 'Gallery' 模型,只有一组可排序关系。
在一般应用程序(或任何地方)中,models.py
class PageGalleryImage(Orderable):
page = ParentalKey(Page,
on_delete=models.CASCADE,
related_name='image_gallery')
image = models.ForeignKey('wagtailimages.Image',
on_delete=models.CASCADE,
related_name='page_gallery_image')
caption = models.CharField(blank=True, max_length=250)
panels = [
ImageChooserPanel('image'),
FieldPanel('caption'),
]
博客等其他应用,models.py:
class BlogPage(Page):
content_panels = Page.content_panels + [
...
InlinePanel('image_gallery', label="Gallery images"),
]
这提供了一个应用程序 = 一个图库。