Django timezone.now() giving the time when i started the server - python

I'm using timezone.now() (django.utils impor timezone) to set the initial date of my model. But, the timezone.now() is fixed to the time when i set the server up, and doesnt change. How can i fix this?
I wanna that the timezone.now() return the datetime when the user is creating an object and not the time when i run the server.

You should pass a reference to the function to it, so:
from django.db import models
from django.utils import timezone
class MyModel(models.Model):
created_at = models.DateTimeField(default=timezone.now)
But likely you want to use auto_now_add=True [Django-doc], which will also make the field non-editable:
from django.db import models
class MyModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)

Related

AttributeError: 'datetime.date' object has no attribute 'tzinfo' Datetime Django

Im having a trouble how to set default date in my models, the format should I have in my database is date not datetime but the resources mostly I find is the code below, Is there any way how to set my models into date? Thanks in advance!
The output/format saved in database should like this
2020-11-24
Format of my date in sql
from datetime import datetime
class Person(models.Model):
date_upload = models.DateTimeField(default=datetime.now().strftime ("%Y-%m-%d"), blank=True)
you should try like this:
from datetime import date
class Person(models.Model):
date_upload = models.DateTimeField(default=date.today(), blank=True)
If you just want the date in the database, without the time, use DateField.
Then just use date.today as the default for the field. Since date.today is a callable, it will call this method each time a new instance of this model is created.
from datetime import date
class Person(models.Model):
date_upload = models.DateField(default=date.today, blank=True))
You can also just use auto_now or auto_now_add to automatically set it to today:
# Set on creation and additional saves
date_upload = models.DateField(auto_now=True, blank=True))
# Only set on creation
date_upload = models.DateField(auto_now_add=True, blank=True))

Django DateTimeField and datetime.datetime.now() giving different times

I have a model where I want the name field to be a string representation of the timestamp, and another field to be the actual time stamp. Here is my model code:
from django.db import models
from datetime import datetime
class Image(models.Model):
name = models.CharField(max_length=255, default=datetime.now().strftime("%Y%m%d-%H%M%S"))
create_date = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to="images/")
Then I go in the django shell and enter this:
>>> import models
>>> models.Image(image='images/rock.png').save()
This works but the only problem is the two times do not align. For example, I get name = 20191201-143119 and create_date = 2019-12-01 14:32:11.445474.
How can I get these two datetimes to be the same?
This is a pretty common gotcha in Django's world. The post mentioned by #eliakin-costa discuss this problem, although his solution works I wouldn't recommend overriding save method to get this behavior as it's easier to create a function (keeping decoupled and explicit):
from django.db import models
from django.utils import timezone
def default_image_name():
return timezone.now().strftime("%Y%m%d-%H%M%S")
class Image(models.Model):
name = models.CharField(max_length=255, default=default_image_name)
create_date = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to="images/")
By the way, did you take a look at this docs (upload_to also accepts a callable) ? Do you really need a name column in your table?
I've linked an answer will help you understand what is happening. Achieving what you want is quite simple though.
models.py
from django.db import models
from datetime import datetime
class Image(models.Model):
name = models.CharField(max_length=255)
create_date = models.DateTimeField(auto_now_add=True)
image = models.ImageField(upload_to="images/")
def save(self, *args, **kwargs):
if not self.name:
self.name = datetime.now().strftime("%Y%m%d-%H%M%S")
super(Image, self).save(*args, **kwargs)

Django - How to filter by annotated value

Consider the following model. I'd like to filter objects based on the latest timestamp, which might be either created_at or updated_at. For some reason, the filter function does not recognise the annotated field and I'm having hard time finding the appropriate code examples to do this simple thing.
The error message is "Cannot resolve keyword 'timestamp' into field.".
How would you retrieve the Example objects within 7 days, based on newer date.
from datetime import timedelta
from django.db import models
from django.db.models.functions import Greatest
from django.utils import timezone
class Example(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(null=True)
#property
def recently_updated(self):
return Event.objects
.annotate(timestamp=Greatest('created_at', 'updated_at'))
.filter(timestamp__gte=timezone.now() - timedelta(days=7))
.order_by('-timestamp')
Django 1.11
Just set updated_at = models.DateTimeField(auto_now=True, null=True), this way when record is inserted for the first time updated_at and created_at will be same, so, you can just run the query on updated_at:
Event.objects.filter(updated_at__gte=timezone.now() - timedelta(days=7)).order_by('-timestamp')

Django Naturaltime is not working in .annotate

Here I just wants to annotate a field on a model that gives human readable format saying how much time elapsed since it's created
My Model is created 30 seconds ago
My Model Description:
from django.db import models
class MyModel(models.Model):
name = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created_at']
#property
def natural_time(self):
return naturaltime(self.created_at)
What I did is here
from django.contrib.humanize.templatetags.humanize import naturaltime
from django.db.models import F
from .models import MyModel
m = MyModel.objects.annotate(timesincecreated=naturaltime(F('created_at'))
print m.values('timesincecreated')
on this print call I am getting the DateTimeField that I used in the model.
But If I want to access the property.
from .models import MyModel
m= MyModel.objects.first()
print m.natural_time
It works.
Any help? TIA.
You cannot use naturaltime function for annotation, annotation is a computation that is done on database level.
Django provides only a set of basic computations which can be processed by the database like Count, Sum, Min, Max, etc. You can refer to official doc to learn more about Query Expressions.

Set default date with Django SelectDateWidget

Firstly, this question has already been asked here, however the answer does not work, and is also for Django 1.3. Having done extensive research on similar questions on SO, the Django Docs, and general Googling, I still can't find a working answer. Not really a major detail, but it's annoying both when trying to use the form I'm creating, and because I can't solve it.
When using the SelectDateWidget in a ModelForm, I want to be able to set the default on the widget to today's date.
forms.py
from django import forms
from .models import Article
from django.utils import timezone
class ArticleForm(forms.ModelForm):
publish=forms.DateField(widget=forms.SelectDateWidget(), initial = timezone.now)
class Meta:
model = Article
fields = [
'title',
...
'publish',
]
models.py
from django.conf import settings
from django.core.urlresolvers import reverse
from django.db import models
from django.utils import timezone
from Blog.models import Category
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(max_length = 120, unique=True)
...
publish = models.DateField(default=timezone.now)
I'm assuming I have some syntax error somewhere, but have had no joy in finding it.
Looks like there's a subtle difference when setting the the default time for DateTimeField and DateField.
DateField.auto_now_add Automatically set the field to now when the
object is first created. Useful for creation of timestamps. Note that
the current date is always used; it’s not just a default value that
you can override. So even if you set a value for this field when
creating the object, it will be ignored. If you want to be able to
modify this field, set the following instead of auto_now_add=True:
For DateField: default=date.today - from datetime.date.today()
For DateTimeField: default=timezone.now - from django.utils.timezone.now()
So, you'll want to use date.today rather than timezone.now.

Categories