Image Gallery ************* .. highlight:: python .. tip:: The ``gallery`` app is part of our *super simple CMS* site which can be cloned from here: https://gitlab.com/kb/hatherleighcommunitymarket_org Issues ====== Freeze / Lock-up ---------------- If you find your development version is freezing up in the ``ImageCreateView`` on this line:: transaction.on_commit(lambda: thumbnail_image.delay(self.object.pk)) To prove this is the issue, comment out the line and see if it works. I think this is caused by some sort of thread issue because Celery is not installed (or set-up). To solve the issue, install :doc:`celery`... Sequence -------- When you first introduce the ``gallery`` app, you may need to reset the sequence for the ``Image`` and ``ImageCategory`` models on Postgres: .. code-block:: sql SELECT setval(pg_get_serial_sequence('gallery_image', 'id'), COALESCE(MAX(id), 0) + 1, false) FROM gallery_image; SELECT setval(pg_get_serial_sequence('gallery_imagecategory', 'id'), COALESCE(MAX(id), 0) + 1, false) FROM gallery_imagecategory; Migrate from block.Image to gallery.Image ========================================= .. note:: The latest version of the ``compose`` app has been updated to use the ``gallery`` app so for a Simple CMS site much of this procedulre is not necessary. All you will need to do is update to the latest version of the block, compose and gallery apps, update the block order if this has not already been done (run the export manangement command on the legacy version of block and after deploying the new version import the order numbers) and then run the sequence commands to update your gallery.Image and gallery.ImageCategory sequence numbers (see below). At present the ``block`` app still has the legacy models for image data, these will be removed in the future if after that time you need to migrate a project add the following temporary models in the ``block`` app:: from taggit.managers import TaggableManager class ImageCategory(models.Model): name = models.CharField(max_length=100) slug = AutoSlugField(max_length=100, unique=True, populate_from=("name",)) deleted = models.BooleanField(default=False) class Meta: ordering = ["name"] verbose_name = "Image Category" verbose_name_plural = "Image Categories" def __str__(self): return "{}".format(self.name) class Image(TimeStampedModel): title = models.CharField(max_length=200) image = models.ImageField(upload_to="link/image") original_file_name = models.CharField(max_length=100) user = models.ForeignKey( settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.CASCADE, related_name="+", help_text="User who uploaded the image", ) deleted = models.BooleanField(default=False) category = models.ForeignKey( ImageCategory, blank=True, null=True, on_delete=models.CASCADE ) tags = TaggableManager(blank=True, related_name="+") class Meta: verbose_name = "Link Image" verbose_name_plural = "Link Images" def __str__(self): return "{}. {}".format(self.pk, self.title) If you had to add these models you will also need to create a migration in the ``block`` app and probably fake apply it:: django-admin.py makemigrations block django-admin.py migrate block django-admin.py migrate --fake block django-admin.py migrate Add the ``gallery`` app to your project or app (see below) and update the ``Image`` model used by your app or project:: from gallery.models import Wizard, Image Create the new migrations and run them. If you added the temporary models to the ``block`` app you can remove them and the migrations once your site is migrated. .. tip:: To get the migrations working, you may need to modify old migrations: Update the model e.g: .. code-block:: diff -- a/blog/migrations/0001_initial.py +++ b/blog/migrations/0001_initial.py @@ -150,7 +150,7 @@ class Migration(migrations.Migration): - to="block.Image", + to="gallery.Image", You may need to switch this back when running the migrations for a project. I got this error:: The field blog.BlogPost.picture was declared with a lazy reference to 'gallery.image', but app 'gallery' isn't installed Add a dependency to ``block``, ``0022_auto_20190203_1346`` e.g:: dependencies = [ ("block", "0022_auto_20190203_1346"), ("blog", "0001_initial"), ] Model ===== .. tip:: The gallery app has example code with a simple model: https://gitlab.com/kb/gallery/blob/master/example_gallery/models.py To use the image gallery, your model needs to inherit from ``WizardModelMixin`` e.g:: from django.db import models from gallery.models import Image, WizardModelMixin class Unit(models.Model, WizardModelMixin): Create a ``ForeignKey`` field named ``picture`` linking to an ``Image``:: picture = models.ForeignKey( Image, related_name="+", blank=True, null=True, on_delete=models.CASCADE, ) .. note:: I think the field name **must** be ``picture``. Create properties and methods for the image wizard:: def get_design_url(self): return reverse("unit.detail", args=[self.pk]) def get_absolute_url(self): return reverse("unit.detail", args=[self.pk]) def set_pending_edit(self): return True @property def wizard_fields(self): return [Wizard("picture", Wizard.IMAGE, Wizard.SINGLE)] .. PJK 30/01/2019, The documentation for ``wizard_fields`` needs expanding! Template ======== The template will render the URLs. The ``wizard_urls`` are generated from the ``wizard_fields`` (see above) by the ``WizardModelMixin``: .. code-block:: html {% with obj.wizard_urls as wizard_urls %} {% if wizard_urls|length %} {% for url in wizard_urls %} {{ url.caption }} {% endfor %} {% endif %} {% endwith %} To display the picture:: {% if unit.picture %} {% endif %} URLs ==== :: url(regex=r"^wizard/", view=include("gallery.urls")),