In Django, I have two Author and Publication models that are associated with the Plenty to Many field, so I can assign different authors to the publication. In addition, I have to use the custom authorship "pass-through" model to determine the correct order.
class Author(models.Model): first_name = models.CharField(max_length=48) ..... class Authorship(models.Model): author = models.ForeignKey(Author) publication = models.ForeignKey('Publication') order_of_authorship = models.IntegerField(default=1) class Publication(models.Model): title = models.CharField(max_length=128) authors = models.ManyToManyField(Author, through=Authorship) year = models.IntegerField(max_length=4) ... citation_key = models.CharField(max_length=9, blank=True, default="")
I am currently using the admin interface to fill out my details with the Publish form and the built-in Authorship form.
What I want to achieve now: An additional citation_key field (for example, "Einstein1950") should be automatically populated after changing the data.
What I tried to do: I found out that using signals should be the best practice.
However, the “m2m_changed” -Signal in “Publication.authors.through” does not start when I change the Automata.
@receiver(m2m_changed, sender=Publication.authors.through) def authors_changed(sender, **kwargs): print("authors changed")
This issue is also discussed in a related section , where the author seems to use post_save in an end-to-end model.
@receiver(post_save, sender=Authorship) def authorship_changed(sender, instance, **kwargs): print("authors changed")
This seems to have worked, but I have to remember that the deletion is not covered yet, so I added the post_delete message:
@receiver(post_delete, sender=Authorship) def authorship_deleted(sender, instance, **kwargs): print("authors deleted")
Now the problem is this: if I add 4 authors, I get this event four times. If I want to update my citation_key as described above, this will happen 4 times.
Could this be the right decision? Or is there a best practice? I assume that it should somehow work with the m2m_changed signal, but I don't know how to do it. Since I'm new to Django, I don't know if this is an obvious solution for you. In addition, in this case, an unnecessary calculation should not have much influence, but it is not very pleasant.
I found only the old error report in Django-Trac, which seems to solve this problem as well. But there is no solution yet.