KB Software Documentation

Standards

  • Glossary
  • Development Security
  • Standards
  • Django / Python Code Standards
  • Documentation
  • HTML Code Standards
  • Ember / JavaScript Code Standards
  • Security Standards - Development
  • Sys-Admin and Configuration Management
  • Technology Standards
  • UI Standards

Sales

  • Sales
  • Hardware Sales

Process

  • Process
  • Development Environment
  • Checklist
  • MatterMost
  • Monitor - Grafana (Loki), Elastic and Raygun
  • Workflow

Customer Support

  • SEO
  • Android
  • Backup (PC/Laptop Repair)
  • Flowable
  • Google Apps
  • Podman
  • postfix
  • Security - Sys-Admin
  • VPN

Master

  • Salt Master
  • devpi

Minion

  • Salt Cloud - Install
  • Salt - Provision
  • Salt Commands
  • Fabric
  • Database
  • Deploy
  • Deploy on Windows
  • Release
  • Search
  • Install SSL Certificate

System Administration

  • Diagnostics
  • Issues
  • Microsoft Azure
  • Bitwarden
  • fail2ban
  • Keycloak
  • ManoMano
  • MatterMost - Install and Update
  • Microsoft (Group Policies)
  • MySQL
  • Nextcloud
  • Nginx
  • NoMachine
  • Microsoft Office 365
  • Postgres
  • Saleor
  • SparkPost
  • Add swap space to a server
  • systemd
  • Ubuntu
  • Uptime Kuma
  • uWSGI

Site

  • Alfresco Community Edition
  • Backup
  • Backup Dropbox
  • Cache
  • Site - Configuration
  • Pillar
  • Rename a Digital Ocean droplet
  • Site Maintenance Mode
  • Authentication
  • Celery (using Redis)
  • Firewall
  • FTP
  • Google
  • Mailgun
  • Maintenance
  • Restore (as a task)
  • SOLR
  • Create SSL Certificate
  • Obtain and configure ssl certificate on nginx with letsencrypt
  • Remove a site from a server

Development - Django

  • Django
  • Django Applications
  • Django Auth
  • Django Field Types
  • Django Filter
  • Django Forms
  • GeoDjango
  • Django Media
  • Django Migrations
  • Django Rest Framework
  • Django Reversion
  • Django Static
  • Django Testing
  • Django Thumbnails
  • Django View
  • Django on Windows

Development

  • Journal
  • Learning
  • APScheduler (with Redis)
  • Development Environment
  • Captcha
  • Chosen - Select Box
  • CKEditor
  • CodeMirror Editor
  • Cookie Confirm
  • Debug
  • Django Debug Toolbar
  • Dramatiq (using Redis)
  • ElasticSearch
  • Deploy a project for the first time
  • Fish Shell
  • Flowable Development
  • git
  • GitLab
  • grunt
  • Google Development
  • LESS
  • Logging
  • Magento XMLRPC API
  • Move a site from Sqlite to Postgresql
  • Pagination
  • PDF Object
  • pytest
  • Requirements
  • Restore
  • S3
  • sass
  • Scripts to aid the development process
  • Shiny
  • SiteMap
  • Social
  • Tailwind
  • Tailwind and Ember
  • Tailwind UI
  • Testing
  • Time zones
  • Wagtail
  • WordPress - Development
  • Web Fonts and favicons
  • Domain

Ember Development

  • Ember
  • Ember AddOns
  • Ember Addons (KB using Tailwind)
  • Ember Authentication
  • Ember Data
  • Ember Patterns
  • Ember Testing

Apps

  • api
  • Apps
  • base
  • block
  • Blog
  • booking
  • Chat
  • Checkout (with Stripe SCA)
  • compose
  • Contact
  • crm
  • enquiry
  • Finance
  • Image Gallery
    • Issues
      • Freeze / Lock-up
      • Sequence
    • Migrate from block.Image to gallery.Image
    • Model
    • Template
    • URLs
  • GDPR
  • Invoice
  • Job
  • login
  • Magento App
  • mail
  • MailChimp
  • Mandrill (do not use)
  • Monitor
  • Microsoft Graph
  • OnBuy
  • Pipeline
  • Q and A
  • Record Management
  • Report
  • Sales Order
  • Sales Order Ticket
  • search
  • Veeqo
  • WooCommerce
  • Work
  • Workflow
  • Xero App

Cloud

  • Digital Ocean

Kubernetes

  • Development with Kubernetes
  • Kubernetes for Development - Install

Project

  • Simple Site (CMS)

PHP

  • PHP - Install
  • PHP - Development
  • PHP - Issues
  • Drupal

WordPress

  • WordPress
  • WordPress - Issues
  • Wordpress Hosting
  • WordPress - Plugins
  • WordPress Security
  • WordPress - Transfer / Migrate
  • WordPress - Update
  • WordPress - WooCommerce

Detailed Notes

  • devpi (in detail)
  • Restore (in detail)
  • LetsEncrypt - DNS
  • Obtain and configure ssl certificate on nginx with letsencrypt - Manual Configuration
  • VPN (Detail)

Old Notes

  • Checkout (before Stripe SCA)
  • pay
  • Old Activiti Notes
  • Adding Angular to Django Project
  • Backup
  • Development with Docker
  • Kubernetes (for development)
  • Old Notes
  • Database
  • Files
  • Backup
  • Monitor
  • Restore - Server
  • Amazon
  • Amazon Database
  • Amazon S3
  • Digital Ocean
  • Salt Cloud - Install (Legacy Notes)
  • Rackspace
  • Salt Masterless
  • Backup (Old Notes)
  • ownCloud
  • WordPress (Old Notes)
KB Software Documentation
  • Image Gallery
  • View page source

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")),
Previous Next

© Copyright 2025, KB Software Ltd.

Built with Sphinx using a theme provided by Read the Docs.