Image Gallery
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 Celery (using Redis)…
Sequence
When you first introduce the gallery
app, you may need to reset the
sequence for the Image
and ImageCategory
models on Postgres:
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 <migrations before the one created above>
django-admin.py migrate --fake block <migration created above>
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:
-- 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)]
Template
The template will render the URLs. The wizard_urls
are generated from the
wizard_fields
(see above) by the WizardModelMixin
:
{% with obj.wizard_urls as wizard_urls %}
{% if wizard_urls|length %}
<small>
{% for url in wizard_urls %}
<a href="{{ url.url }}">
<i class="{{ url.class }}"></i>
{{ url.caption }}
</a>
{% endfor %}
</small>
{% endif %}
{% endwith %}
To display the picture:
{% if unit.picture %}
<img src="{% thumbnail unit.picture.image '150x0' %}">
{% endif %}
URLs
url(regex=r"^wizard/", view=include("gallery.urls")),