Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enforce auto_now when using save(update_fields = […])

Model definitions:

class Footprint(models.Model)
  date = models.DateTimeField(auto_now = True)

class Stuff(Footprint):
  name = models.CharField(max_length = 255)
  some_other_field = models.CharField(max_length = 255)

In a Stuff object, I'd like to only update the name field, and leave all the other fields unchanged, except those defined in the associated Footprint object.

Fields in the Footprint object are correctly updated if I don't use update_fields:

s = Stuff.objects.get(pk = 1)
s.name = 'Alexander'
s.save()

s.date # is correctly set

But if I specify fields to update, the associated Footprint is not not even saved.

s = Stuff.objects.get(pk = 1)
s.name = 'Tim'
s.save(update_fields = ['name'])

s.date # unfortunately, remains unchanged!!

I have to use update_fields to avoid interferences between several scripts.

At the same time, I'd like to always keep track of the last modification, defined by the "Footprint" object (it contains the last modification date, as well as several other fields; their update is triggered by a custom save() method).

Is there a way to force a call to Footprint.save() even if update_fields doesn't contain any field from Footprint?

like image 246
alexpirine Avatar asked Dec 27 '22 00:12

alexpirine


1 Answers

It was enough to simply rewrite the Footprint model definition like this:

class Footprint(models.Model)
  date = models.DateTimeField(auto_now = True)

  def save(self, *args, **kwargs):
    if kwargs.has_key('update_fields'):
      kwargs['update_fields'] = list(set(list(kwargs['update_fields']) + ['date']))

    return super(Footprint, self).save(*args, **kwargs)

Of course, if you have more fields to update than just a date field, you just have to append them in the list.

like image 92
alexpirine Avatar answered Jan 03 '23 00:01

alexpirine