Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: models last mod date and mod count

I have a django model called Blog.

I'd like to add a field to my current model that is for last_modified_date. I know how to set a default value, but I would like somehow for it to get automatically updated anytime I modify the blog entry via the admin interface.

Is there some way to force this value to the current time on each admin site save?

Also would there be some way to add a mod_count field and have it automatically calculated on each modify of the admin site blog entry?

like image 656
Net Citizen Avatar asked Aug 04 '09 23:08

Net Citizen


People also ask

What is __ str __ In Django model?

str function in a django model returns a string that is exactly rendered as the display name of instances for that model.

What is timestamped model in Django?

TimeStampedModel - An Abstract Base Class model that provides self-managed created and modified fields.

How Django knows to update VS insert?

The doc says: If the object's primary key attribute is set to a value that evaluates to True (i.e. a value other than None or the empty string), Django executes an UPDATE. If the object's primary key attribute is not set or if the UPDATE didn't update anything, Django executes an INSERT link.

WHAT IS models ForeignKey?

ForeignKey is a Django ORM field-to-column mapping for creating and working with relationships between tables in relational databases. ForeignKey is defined within the django. db.


2 Answers

Create a DateTimeField in your model. Have it update whenever it is saved. This requires you to use the auto_now_add option:

class DateTimeField([auto_now=False, auto_now_add=False, **options])

DateTimeField.auto_now_add¶

Automatically set the field to now every time the object is saved. Useful for "last-modified" timestamps. Note that the current date is always used; it's not just a default value that you can override.

It should look something like this:

class Message(models.Model):
    message = models.TextField()
    active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now_add=True)

Model field reference

For the second part, I think you have to overload

ModelAdmin.save_model(self, request, obj, form, change)

As James Bennett describes here. It will look something like this:

class EntryAdmin(admin.ModelAdmin):

def save_model(self, request, obj, form, change):
    if change:
        obj.change_count += 1
    obj.save()
like image 198
hughdbrown Avatar answered Sep 25 '22 21:09

hughdbrown


The accepted answer is no longer correct.

For newer django versions, you will have to use the auto_now=True parameter rather than the auto_now_add=True, which will only set the field value when the object is initially created.

From the documentation:

DateField.auto_now_add¶

Automatically set the field to now when the object is first created. Useful for creation of timestamps.

The desired functionality is now implemented by auto_now:

DateField.auto_now¶

Automatically set the field to now every time the object is saved.

So to achieve self-updating timestamps a model should be created like this:

class Message(models.Model):
    message = models.TextField()
    active = models.BooleanField(default=True)
    created_at = models.DateTimeField(auto_now=True)
    mod_count = models.IntegerField(default=0)

To increment mod_count everytime this model is modified overload the model's save() method:

    def save(self, *args, **kwargs):
        self.mod_count +=1
        return super(Message,self).save(*args, **kwargs)
like image 24
Sebastian Wozny Avatar answered Sep 23 '22 21:09

Sebastian Wozny