简体   繁体   中英

Django - get auto_now field in pre_save signal

I'm using Django 2.1.5.

There is a model with 'auto_now' field:

class BaseModel(models.Model):
    id = models.UUIDField(default=uuid.uuid4, editable=False, db_index=True, unique=True, primary_key=True)
    updated_at = models.DateTimeField(db_index=True, auto_now=True)
    updated_by = models.CharField(max_length=200)
    responded_at = models.DateTimeField(db_index=True, null=True, blank=True)
    responded_by = models.CharField(max_length=200, null=True, blank=True)

Now, I have a pre_save signal for that model, and I want to update there the responded_at and responded_by fields to be equal to updated_at and updated_by . In that signal - the updated_by value is already the new one, as supposed to be in the end of the request, but the updated_at is not. It's the old (current) value. I want, if possible, to be able to get the value that supposed to be in updated_at field after the save.

The reason I'm using pre_save signal and not post_save is because I'm updating the instance inside it.

Since your are using auto_now with your updated_at field, it will inherit editable=False and blank=True .

As the docs state:

As currently implemented, setting auto_now or auto_now_add to True will cause the field to have editable=False and blank=True set.

To avoid this, you can write a custom field like this:

from django.utils import timezone


class AutoDateTimeField(models.DateTimeField):
    def pre_save(self, model_instance, add):
        return timezone.now()

You can use this in your BaseModel like this:

class BaseModel(models.Model):
    updated_at = models.AutoDateTimeField(default=timezone.now)
    # ...

This way the updated_at field should be editable and your signal should work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM