Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Temporarily disable auto_now / auto_now_add

I have a model like this:

class FooBar(models.Model):     createtime = models.DateTimeField(auto_now_add=True)     lastupdatetime = models.DateTimeField(auto_now=True) 

I want to overwrite the two date fields for some model instances (used when migrating data). The current solution looks like this:

for field in new_entry._meta.local_fields:     if field.name == "lastupdatetime":         field.auto_now = False     elif field.name == "createtime":         field.auto_now_add = False  new_entry.createtime = date new_entry.lastupdatetime = date new_entry.save()  for field in new_entry._meta.local_fields:     if field.name == "lastupdatetime":         field.auto_now = True     elif field.name == "createtime":         field.auto_now_add = True 

Is there a better solution?

like image 207
jedie Avatar asked Sep 21 '11 12:09

jedie


People also ask

Is there a way to disable Auto_now_add in the admin panel?

Any field with the auto_now attribute set will also inherit editable=False and therefore will not show up in the admin panel. There has been talk in the past about making the auto_now and auto_now_add arguments go away, and although they still exist, I feel you're better off just using a custom save () method.

Is Auto_now_add still a thing in Django?

According to more recent discussions (django bugs #7634 and #12785 ), auto_now and auto_now_add are not going anywhere, and even if you go to the original discussion, you'll find strong arguments against the RY (as in DRY) in custom save methods.

How to replace auto_now_add=true with editable=false?

It is sufficient to replace auto_now_add=True by the equivalent default=timezone.now, editable=False, blank=True (according to docs ). The latter two options ensure similar behavior in the admin. You can also use the update_fields parameter of save () and pass your auto_now fields. Here's an example:


1 Answers

I've recently faced this situation while testing my application. I needed to "force" an expired timestamp. In my case I did the trick by using a queryset update. Like this:

# my model class FooBar(models.Model):     title = models.CharField(max_length=255)     updated_at = models.DateTimeField(auto_now=True, auto_now_add=True)    # my tests foo = FooBar.objects.get(pk=1)  # force a timestamp lastweek = datetime.datetime.now() - datetime.timedelta(days=7) FooBar.objects.filter(pk=foo.pk).update(updated_at=lastweek)  # do the testing. 
like image 185
dirleyrls Avatar answered Oct 12 '22 19:10

dirleyrls