You probably do not need a custom image
model to achieve this goal, Django has a built in system called signals
. This lets you listen to creation & editing (plus others) of any existing Django model and modify the data before it is saved to the DB.
A good example of this in use already in Wagtail is the feature detection system, which will automatically add a focal point on save if faces are detected.
You can see how this has been implemented in the source code, wagtail/images/signal_handlers.py.
You may need to understand how to build up a focal point, depending on how you want to calculate it but basically you need to call set_focal_point
on your image instance. This method must be supplied an instance of a Rect
which can be found in the source at images/rect.py
.
It is important to understand how to call your signal handlers registration function, I found this Stack Overflow answer to be helpful. However, it might be simpler to just add it to your wagtail_hooks.py
file as you know it will be run at the right time (when the app is ready & models are loaded.
You can read more at the Django docs for app.ready() if you would prefer not to rely on the wagtail_hooks.py
approach.
Example Implementation
myapp/signal_handlers.py
from django.db.models.signals import pre_save
from wagtail.images import get_image_model
from wagtail.images.rect import Rect
def pre_save_image_add_auto_focal_point(instance, **kwargs):
# Make sure the image doesn't already have a focal point
# add any other logic here based on the image about to be saved
if not instance.has_focal_point():
# this will run on update and creation, check instance.pk to see if this is new
# generate a focal_point - via Rect(left, top, right, bottom)
focal_point = Rect(15, 15, 150, 150)
# Set the focal point
instance.set_focal_point(focal_point)
def register_signal_handlers():
# important: this function must be called at the app ready
Image = get_image_model()
pre_save.connect(pre_save_image_add_auto_focal_point, sender=Image)
myapp/wagtail_hooks.py
from .signal_handlers import register_signal_handlers
register_signal_handlers()