1

Let's say i need to call my own function def do_stuff() after i save model. If that model would be in app which i have created, that would be no problem. I could do:

def save(self, *args, **kwargs):
        super(Post, self).save(*args, **kwargs)
        do_stuff()

But i need to call save() in 3rd party app when model is saved. I can think of only copying all project to my local directory and append save() method, but that is not nice since i have to copy all app code. Is there any nicer way to do this?

EDITED:

apps.py:

from django.apps import AppConfig

class SubscriptionConfig(AppConfig):

    def ready(self):
        import subscription.signals

signals.py:

from django.db.models.signals import post_save
from django.dispatch import receiver

from djangocms_blog.models import Post

@receiver(post_save, sender=Post)
def send_emails(instance, **kwargs):
    print 'instance %s' %instance

__init__.py:

default_app_config = 'subscription.apps.SubscriptionConfig'
Mažas
  • 387
  • 1
  • 6
  • 19

2 Answers2

3

There are signals that are dispatched after some certain events. One of them, post_save (or pre_save if you want to do something just before the object is saved) would work in your case.

To be more specific, create a signals.py in your app's folder:

from django.db.models.signals import post_save
from django.dispatch import receiver

from your_project.your_app.models import YourModel

@receiver(post_save, sender=YourModel)
def do_stuff(instance, **kwargs):
    # instance here is your object, you can use or modify it
    instance.title = "New title"

    # don't forget to save your object if you edit
    instance.save()

And then make sure this signals.py is imported in somewhere. It is recommended to do it in app's apps.py:

from django.apps import AppConfig


class YourAppConfig(AppConfig):
    name = 'your_projects.your_app'
    verbose_name = "Your app's verbose name"

    def ready(self):
        from your_project.your_app import signals

As last step, make sure your app uses the AppConfig you defined there. Open app's __init__.py and put this:

default_app_config = 'your_projects.your_app.apps.YourAppConfig'

Now, every time the signal you selected dispatches, your handler function will be run.

Gokhan Sari
  • 7,185
  • 5
  • 34
  • 32
  • in `myprocject/myapp` i created `signals.py` and `apps.py` files, modified `__init__.py`, but none of these gets compiled. – Mažas Jul 02 '16 at 16:42
  • It's hard to guess. Can you please add the contents of those files to your question? – Gokhan Sari Jul 02 '16 at 16:46
  • In my app `models.py` at the end of file added `import subscription.signals` and now it works. Also deleted `apps.py` and cleared `__init__.py` file. – Mažas Jul 02 '16 at 17:26
  • Note django version. In my case i have 1.6.10, which according to http://stackoverflow.com/a/21612050/5607745 answer, i need import signals in `models.py`. – Mažas Jul 02 '16 at 17:29
0

You can use post_save signal. It will be invoked after model is saved.

Arun Ghosh
  • 7,634
  • 1
  • 26
  • 38