Question

I have class Event and class Participant, which has foreign key to Event. In Event I have:

model_changed_stamp = models.DateTimeField()

Many participant are taking part in one even.

When any of the instances of class Event changes, or the new one is being created I would like that the value in model_changed_stamp will be updated. In fact I have many other classes like Building, which also have foreign key to Event, and I would like to also keep track of changes.

I came up with idea to use instance class method in Event. I tried:

def model_changed(self):
    value = getattr(self, 'model_changed_stamp')
    value = datetime.now()
    setattr(self, 'model_changed_stamp', value)

and then in save() of Participant, or Building I would like to fire self.event.model_changed()

I would like know how to do it RIGHT. Should I use signals?


UPDATE 0: According to some reading (e.g Two scoops of Django) use of signals is an overkill for this case.


UPDATE 1: Following suggestions of Daniel Roseman in Participant class in save(self) method I try:

def save(self):
    if self.id is None:
        self.event.model_changed()

In Event I defined model_changed as follows:

def model_changed(self):
    self.model_changed_stamp = datetime.now()
    self.save()

And it is not working - not updating the date, when it should i.e when the new Participant is created.

UPDATE 2: WORKING!!! ;-)

after adding: self.save() as last line in model_changed method.

Was it helpful?

Solution

Why not just set it directly? Why all this mucking about with getattr and setattr?

def model_changed(self):
    self.model_changed_stamp = datetime.datetime.now()

An even better solution is to define the fields with auto_now=True, so they will be automatically updated with the current time whenever you save.

OTHER TIPS

Yeah, signals is good tool for your task.

You can wite:

model_changed_stamp = models.DateTimeField(auto_now=True)

check docs for auto_now feature.

and then:

from django.db.models.signals import post_save

@receiver(post_save)
def post_save_event_handler(sender, instance, **kwargs):
    if not sender in [Building, Participant, ...]:
        return

    instance.event.save() #updates model_changed_stamp
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top