Reputation: 609
I have a model that contains multiple many to many fields:
class Author(models.Model):
name = models.CharField(max_length=30)
class Topic(models.Model):
description = models.CharField(max_length=30)
class Article(models.Model):
authors = models.ManyToManyField(Author, related_name='articles')
topics = models.ManyToManyField(Topic, related_name='articles')
I need something pretty simple:
A method to be executed after the article is saved where I can access both authors and topics of that instance.
My first attempt has been with a post_save
signal, but the signal is fired when the model itself is saved, not after its relationships are saved, which come from a through model obviously.
After some online reading I realized that I probably need to create my own signal and connect to it. The problem is that I have no idea what to overwrite and where to fire that signal.
Since I need this on multiple models, I thought I could create some M2MPostSaveModel
class and have my models inherit it so I can just catch the signals..
But where does Django sends the signals? How can I overwrite it? I honestly have no idea and I had no luck searching in the docs, so apologies if it was there already and I didn't see it.
Upvotes: 1
Views: 659
Reputation: 609
I finally did it, here's how: I created a new signal
import django.dispatch
m2m_post_save = django.dispatch.Signal(providing_args=["instance"])
Then I created a subclass of the ModelAdmin class that fires it after it finishes saving the related elements:
class M2MPostSaveModelAdmin(ModelAdmin):
def save_related(self, request, form, formsets, change):
super(M2MPostSaveModelAdmin, self).save_related(request, form, formsets, change)
m2m_post_save.send(sender=self.__class__, instance=form.instance)
Now all I have to do is to subclass my ModelAdmin class with my M2MPostSaveModelAdmin class and hook up the signal to my method.
def doo_something_with_updated_instance(instance, **kwargs):
# Here your instance has all the m2m relationships updated
m2m_post_save.connect(doo_something_with_updated_instance sender=YourModelAdminClass)
Upvotes: 3
Reputation: 10315
I used m2m_changed
for separate processing.
def topics_changed(sender, instance, **kwargs):
# Do something
m2m_changed.connect(topics_changed, sender=Article.topics.through)
so do with authors
also
Upvotes: 0