如何从压缩档案中制作图像库?

问题描述 投票:1回答:1

我有一个项目,我有想法制作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内没有任何项目,不知道为什么。

python python-3.x wagtail
1个回答
1
投票

我需要创建wagtail_hooks.py文件,并且,如docs所述,在那里定义钩子:

models.朋友:

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.朋友:

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()
© www.soinside.com 2019 - 2024. All rights reserved.