'django update model doesn't affect auto_now timestamp
I've been trying to debug why the last_updated field in several of my models wasn't being updated when doing eg model.objects.filter(**lookups).update(**defaults)
with eg:
class PaymentMethod(models.Model):
MONTHLY_DIRECT_DEBIT = 'MDD'
QUARTERLY_DIRECT_DEBIT = 'QDD'
CASH_OR_CHEQUE = 'CAC'
PAY_IN_ADVANCE = 'PYM'
PAYMENT_CHOICES = (
(MONTHLY_DIRECT_DEBIT, 'Monthly Direct Debit'),
(QUARTERLY_DIRECT_DEBIT, 'Quarterly Direct Debit'),
(CASH_OR_CHEQUE, 'Cash or Cheque'),
(PAY_IN_ADVANCE, 'Pay Monthly in Advance'),
)
unique_id = models.CharField(max_length=3, choices=PAYMENT_CHOICES)
last_updated = models.DateTimeField(auto_now=True)
def __str__(self):
Here I am just trying to update a single entry and don't need to load the instance into memory. This seems to be a won't fix 'bug' explained in docshttps://code.djangoproject.com/ticket/15566 (for some reason I can't see it in the docs).
However, what is the best way to update a single row including the last_updated field (without needing to load into memory)?
Solution 1:[1]
I know the documented behavior is that .update()
will ignore updating auto_now[_add]
fields as is also confirmed by Yunti's answer. However, for those who wish to force the desired effect - for example, having an auto_now
field updated as part of an .update()
invocation, the following approach seems to work...
update(field1=val1, field2=val2,..., last_update=datetime.now())
Where last_update
is a models.DateTime
type field with (or without) auto_now=True
. However, note that if you pass some other value to this field other than now()
- the current timestamp that is, the ORM doesn't help in correcting this to the current timestamp (which is what the auto_now
flag semantics imply). So, for example, in the following snippet, the last_update
field does get overridden with the specified timestamp, irrespective of whether it's past, present or future...
update(field1=val1, field2=val2,..., last_update=datetime.strptime('Jun 1 2005 1:33PM', '%b %d %Y %I:%M%p'))
So, if you wish to enforce the standard semantics of auto_now
when making your calls to update()
, ensure to correctly pass the current timestamp as the update value to these fields. You are doing it manually (due to a flaw/deficiency in the Django ORM implementation), but you are doing it correctly thus.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | JWL |