Automatically changing Django model field on update for one field and freezing one-time write-only for another?
Question:
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?
Answers:
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
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?
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