0

Is there a onupdate parameter for Django's model fields?

For example, in Flask with SQLAlchemy, it's possible to do something like the following with the onupdate=... parameter for the database schema's db.Column():

import datetime

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    created_on = db.Column(db.Text, default=datetime.datetime.utcnow().isoformat())
    updated_on = db.Column(db.Text, default=datetime.datetime.utcnow().isoformat(), 
                           onupdate=datetime.datetime.utcnow().isoformat())

From the docs, there's an auto_now parameter, is that the same thing as the onupdate=... parameter in in SQLAlchemy's db.Column()

I've tried the following model object to emulate the Flask's code above but how could I get the same onupdate=... "effect" in Django?

from django.db import models
from django.utils.timezone import now

class User(models.Model):
    id = models.IntegerField()
    created_on = models.DateTimeField(default=now)
    updated_on = models.DateTimeField(default=now)
    name = models.CharField(default='blah blah')

How do I "freeze" the value for the create_on field such that it can only be added once and never to be changed again afterwards?

But for the updated_on, it changes every time I change the values of the User, e.g. if I created a User and save, then change the name afterwards, created_on should remain the same but updated_on is automatically updated?

davidism
  • 121,510
  • 29
  • 395
  • 339
alvas
  • 115,346
  • 109
  • 446
  • 738
  • Possible duplicate of [django does django have an automatic timestamp create/update field like cakephp?](http://stackoverflow.com/questions/10979488/django-does-django-have-an-automatic-timestamp-create-update-field-like-cakephp) – dirn Jun 09 '16 at 03:24
  • 2
    Before addressing the substance of your question—all your examples are wrong in that you're passing the result of calling a function (`now()`) rather than the function itself (`now`). Let us know that that's not the source of your problem. – Kevin Christopher Henry Jun 09 '16 at 03:26
  • Thanks Kevin for noting that! Nope, that's not the source of the problem. Looks like the post to duplicated question might be related. – alvas Jun 09 '16 at 03:29

1 Answers1

5

In django you have the auto_now_add and auto_now optional arguments for models.DateTimeField

class User(models.Model):
    id = models.IntegerField()
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    name = models.CharField(default='blah blah')

auto_now_add will set the field to the current time when an object is created and auto_now will set the field to the current time when an object is created or updated. You should be aware of some quirky behaviour though:

The field is only automatically updated when calling Model.save(). The field isn’t updated when making updates to other fields in other ways such as QuerySet.update(), though you can specify a custom value for the field in an update like that.

More info in the docs at https://docs.djangoproject.com/en/1.9/ref/models/fields/#datetimefield and https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.DateField

A. J. Parr
  • 7,731
  • 2
  • 31
  • 46