我有一个项目,我想让wagtail
Page
用户可以在管理部分上传zip
图片存档。然后我想解压缩此存档并将每个解压缩的图像放到与此页面相连的图像库中:
import urllib.parse
import os
import zipfile
from django.db import models
from django.conf import settings
from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel, InlinePanel
from wagtail.wagtailsearch import index
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtailimages.models import Image
from taggit.models import TaggedItemBase
from modelcluster.fields import ParentalKey
from modelcluster.contrib.taggit import ClusterTaggableManager
from .forms import PhotoEventPageForm
from utils import get_paginated_pages, get_all_tags
...
class PhotoEventPage(Page):
photos = models.FileField(upload_to=directory_path)
photos_unpacked = models.BooleanField(default=False)
...
base_form_class = PhotoEventPageForm
def main_image(self):
gallery_item = self.gallery_images.first()
if gallery_item:
return gallery_item.image
else:
return None
def save(self, *args, **kwargs):
if os.path.isfile(self.photos.path) and not self.photos_unpacked:
with zipfile.ZipFile(self.photos.path, "r") as zip_ref:
for file_name in zip_ref.namelist():
zip_ref.extract(
file_name,
path=os.path.dirname(self.photos.path))
# now i have image file, this line prints True:
# print(os.path.isfile(os.path.join(os.path.dirname(self.photos.path), file_name)))
# so now I have saved image and i want to create Image gallery,
# I've tried this code:
# img = Image()
# img.save()
# gallery_img = PhotoEventPageGalleryImage(
# image_id=img.id, page_id=self.id)
# gallery_img.save()
# but it's not working
self.photos_unpacked = True
return super().save(*args, **kwargs)
class PhotoEventPageGalleryImage(Orderable):
page = ParentalKey(PhotoEventPage, related_name='gallery_images')
image = models.ForeignKey(
'wagtailimages.Image', on_delete=models.CASCADE, related_name='+'
)
caption = models.CharField(blank=True, max_length=250)
panels = [
ImageChooserPanel('image'),
FieldPanel('caption'),
]
但它没有用,我不知道如何从解压缩的图片中创建wagtail.wagtailimages.models.Image
实例,当我解开这段代码时:
img = Image()
img.save()
gallery_img = PhotoEventPageGalleryImage(
image_id=img.id, page_id=self.id)
gallery_img.save()
我得到了NOT NULL constraint failed: wagtailimages_image.width
。那么也许有办法做到这一点?
经过一些谷歌搜索,感谢Paulo Scardine,还检查了: this 我提出了以下代码:
from django.core.files.images import ImageFile
from wagtail.wagtailcore.models import Page, Orderable
from wagtail.wagtailcore.fields import RichTextField
from wagtail.wagtailadmin.edit_handlers import FieldPanel, InlinePanel
from wagtail.wagtailsearch import index
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtailimages.models import Image
from taggit.models import TaggedItemBase
...
class PhotoEventPage(Page):
...
def save(self, *args, **kwargs):
if os.path.isfile(self.photos.path) and not self.photos_unpacked:
with zipfile.ZipFile(self.photos.path, "r") as zip_ref:
for file_name in zip_ref.namelist():
zip_ref.extract(
file_name,
path=os.path.dirname(self.photos.path))
# print(os.path.isfile(os.path.join(os.path.dirname(self.photos.path), file_name)))
image_file = open(
os.path.join(
os.path.dirname(
self.photos.path), file_name), "rb")
image = Image(
title="Image title",
file=ImageFile(image_file, name=file_name),
)
image.save()
image_file.close()
gallery_img = PhotoEventPageGalleryImage(
image_id=image.id, page_id=self.id)
gallery_img.save()
self.photos_unpacked = True
return super().save(*args, **kwargs)
这很奇怪,我的意思是它确实无误地工作,我可以保存PhotoEventPage
而不会出现错误并提取图片,但self.gallery_images
内没有任何项目保存后,不知道为什么。
答案 0 :(得分:1)
我需要创建wagtail_hooks.py
文件,并且如docs中所述,在那里定义钩子:
<强> models.py 强>:
from wagtail.images.models import Image
...
class ExtenedWagtailImage(Image):
filepath = models.FilePathField()
class PhotoEventPageGalleryImage(Orderable):
page = ParentalKey(PhotoEventPage, related_name='gallery_images')
image = models.ForeignKey(
ExtenedWagtailImage, on_delete=models.CASCADE, related_name='+'
)
caption = models.CharField(blank=True, max_length=250)
panels = [
ImageChooserPanel('image'),
FieldPanel('caption')
]
<强> wagtail_hooks.py 强>:
import os
import zipfile
from django.core.files.images import ImageFile
from django.db import IntegrityError
from wagtail.core import hooks
from .models import PhotoEventPageGalleryImage, ExtenedWagtailImage as EWI
@hooks.register('after_edit_page')
@hooks.register('after_create_page')
def create_gallery(request, page):
if page.__class__.__name__ == 'PhotoEventPage':
with zipfile.ZipFile(page.photos.path, "r") as zip_ref:
for file_name in zip_ref.namelist():
image_file_path = os.path.join(
os.path.dirname(page.photos.path), file_name)
if not os.path.isfile(image_file_path):
zip_ref.extract(
file_name,
path=os.path.dirname(page.photos.path))
with open(image_file_path, "rb") as image_file:
try:
image_obj, created = EWI.objects.get_or_create(
filepath=image_file_path,
defaults={
'file': ImageFile(image_file, name=file_name),
'title': file_name}
)
# if it's not an image
except IntegrityError:
continue
photo_event_amount = len(
PhotoEventPageGalleryImage.objects.filter(
page_id=page.id, image_id=image_obj.id))
if created or photo_event_amount == 0:
PhotoEventPageGalleryImage(
image_id=image_obj.id, page_id=page.id).save()