2

I have a model:

class Object(Object1):
    name = models.CharField(max_length=255, blank=True)
    description = models.TextField(blank=True)
    date_updated = models.DateTimeField(blank=True, null=True)

I want to track if there is anything inserted into the date_updated field, then create another object in another model, without overriding the save method.

For example:

if date_updated:
    MyModel.objects.create(type="D", user=request.user)

Although I have tried this, but still no success.

Community
  • 1
  • 1
arrt_
  • 369
  • 1
  • 6
  • 15
  • "without overriding the save method" - why do you have this requirement? – alecxe Apr 13 '16 at 13:43
  • Could you also add the code which you have tried? – AKS Apr 13 '16 at 13:44
  • 1
    have you considered using the `post_save` signal ? – karthikr Apr 13 '16 at 13:46
  • it is actually not a requirement, I just tried to override the save method, i also tried signals, and all the possible solutions in the link attached above, but no success. – arrt_ Apr 13 '16 at 13:46
  • Django signals like `pre_save` or `post_save` could be useful: https://docs.djangoproject.com/en/1.9/ref/signals/ – Shang Wang Apr 13 '16 at 13:47
  • AKS, karthikr, shang wang, i tried [this](http://stackoverflow.com/a/1361547/5475621) and [this](http://stackoverflow.com/a/7934958/5475621) links, at least. also tried others. – arrt_ Apr 13 '16 at 13:52

2 Answers2

8

You can use tracker field from django-model-utils.

Add a tracker to the model:

class Object(Model):
    name = models.CharField(max_length=255, blank=True)
    description = models.TextField(blank=True)
    date_updated = models.DateTimeField(blank=True, null=True)

    tracker = FieldTracker()

You can check in save() or in other places where you usually update the model:

if object.tracker.has_changed('date_updated'):

    create_new_object(data)
Ibrohim Ermatov
  • 2,169
  • 19
  • 13
0

Sorry, just noticed that you are referencing request.user. So this will NOT work for you. Since you need the particular request object, its probably best done in the view that the request object is referring to.

With pre_save you could compare the current instance's property value with the one currently in the database.

@receiver(pre_save, sender=MyModel)
def check_date(sender, instance=None, created=False, **kwargs):
    changed = created or instance.date_updated != MyModel.objects.get(pk=instance.pk).date_updated

    if changed:
        MyModel.objects.create(type="D", user=request.user)

Didn't test it, though.

C14L
  • 12,153
  • 4
  • 39
  • 52