I have a m2m relation between two models Plot and Station. The m2m field is declared inside the Station model.
When a user create/update a station or a plot, I want to run a 'download' function to create some config files (which will be used from another program) using data from the database. I added this function in the save and delete methods. But it did not work when the m2m field is changed. It seems the 'download' function is called before the m2m field is saved.
I have found that adding a receiver to check m2m_changed on Station model, solves this problem (even if it means running the function twice).
My issue now is that when a user delete a plot, the station will be updated in the database as expected, but I can not figure out how to run the 'download' function on the station after this has been done.
stations/models.py
class Station(models.Model):
name = CICharField(
max_length=50,
unique=True,
error_messages={
"unique": _("That name already exists."),
},
)
...
# list of plots available for the station
plots = models.ManyToManyField(
Plot,
blank=True,
related_name="stations",
)
...
def save(self, *args, **kwargs):
""" """
super().save(*args, **kwargs)
from .util import download_station
download_station()
def delete(self, *args, **kwargs):
""" """
super().delete(*args, **kwargs)
from .util import download_station
download_station()
@receiver(m2m_changed, sender=Station.plots.through)
def update_station_m2m(sender, instance, action, *args, **kwargs):
"""wait unitl change in Many2Many field get saved"""
if "post" in action:
from .util import download_station
download_station()
plots/models.py
class Plot(models.Model):
name = CICharField(
max_length=250,
unique=True,
error_messages={
"unique": _("That name already exists."),
},
)
...
def save(self, *args, **kwargs):
""" """
super().save(*args, **kwargs)
# update config files
from .util import download_plot
download_plot()
def delete(self, *args, **kwargs):
""" """
super().delete(*args, **kwargs)
# update config files
from .util import download_plot
download_plot()
Actually I could do what I want it if I add a call to the download_station in the delete function of plot.
plots/models.py
class Plot(models.Model):
name = CICharField(
max_length=250,
unique=True,
error_messages={
"unique": _("That name already exists."),
},
)
...
def save(self, *args, **kwargs):
""" """
super().save(*args, **kwargs)
# update config files
from .util import download_plot
download_plot()
def delete(self, *args, **kwargs):
""" """
super().delete(*args, **kwargs)
# update config files
from .util import download_plot
from src.stations.util import download_station
download_plot()
download_station()
But I thought the change on the m2m field, which is detected and saved on the database, will also run the save or update_station_m2m function of the Station model.