Here is what is run on pre_delete of model Document. This code gets royally ignored when put in a separate file (signals.py) as suggested best practice. When put in model file, it works fine.
from django.db.models.signals import pre_delete, pre_save
from django.dispatch import receiver
from _myTools.functions import ImageProcessing
from content_image.models import Document
import os
# Image deletion when deleting entire entry
@receiver(pre_delete, sender=Document, dispatch_uid='document_delete_signal')
def entry_deletion_images_delete(sender, instance, using, **kwargs):
for key, value in instance.imageSizes.items():
name_of_image_field = str(getattr(instance, key)) # Converts to string, if not is object itself
os.remove(instance.baseDir + name_of_image_field)
setattr(instance, key, None)
So what is the problem ? Should I import something more in there ? Or should I import this file somewhere ?
The problem is that if you put it in a signals.py
(as recommended) but do nothing more, then nobody will be importing that file.
You should follow this advice, in particular
In practice, signal handlers are usually defined in a signals submodule of the application they relate to. Signal receivers are connected in the ready() method of your application configuration class. If you’re using the receiver() decorator, simply import the signals submodule inside ready().
The ready()
is reponsible for importing the module and thus provoking the signal "connection" and allows the signal receiver to work.
The full procedure should be:
# my_app/__init__.py
default_app_config = 'my_app.apps.ConfigForMyApp'
and the apps.py should be:
# my_app/apps.py
from django.apps import AppConfig
class ConfigForMyApp(AppConfig):
# Optionally add `name` and `verbose_name`
# for the app
def ready(self): # overriding the ready method
# This will trigger the @receiver decorator
# and thus connect the signals
import my_app.signals
Though the answer provided by MariusSiuram is the new recommended way for django >= 1.7, here is another pattern which would work irrespective of the version of django:
In your models.py file:
from django.db.models.signals import pre_delete
from myapp.signals import pre_delete_signal_dispatcher
pre_delete.connect(pre_delete_signal_dispatcher, sender=MyModel, dispatch_uid="delete_signal_dispatch")
This way, the signals are connected when models.py file is parse, and triggered on pre_delete event, and you can continue to grow your signals.py file. But yes, if the number of signal connections grow, it is easier to manage them in the app config.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With