Reputation: 991
I have a model that looks like this:
class Item(models.Model):
...
publish_date = models.DateTimeField(default=datetime.datetime.now)
...
And a manager that looks like this:
from datetime import datetime
class ItemManager(Manager):
def published(self):
return self.get_query_set().filter(publish_date__lte=datetime.now()
And a view that looks like this:
class ItemArchive(ArchiveIndexView):
queryset = Item.objects.published()
date_field = 'publish_date'
The idea being that I can call Item.objects.published()
and get a queryset of all published Items
.
The problem is that Django seems to be executing the datetime.now()
call in the manager when the server is started and then caching that value. So if today is May 24th, and I created an Item
with a publish date of May 23rd, and started the server on May 22nd, that May 23rd item will not show up in the ItemArchive
view. As soon as I restart Apache, the May 23rd item shows up in the view correctly.
How can I force Django to execute datetime.now()
every time the manager is called?
Upvotes: 6
Views: 1787
Reputation: 239430
Don't use the queryset
class variable, and override get_queryset
instead. In general, I think queryset
is a bit of a red herring. If you just specify model
instead, Django automatically sets the queryset to self.model.objects.all()
. If you need any filtering, 99 times out of 100 you'll need to override get_queryset
to be thread-safe. Try the following instead.
class ItemArchive(ArchiveIndexView):
model = Item
date_field = 'publish_date'
def get_queryset(self):
return super(ItemArchive, self).get_queryset().published()
Upvotes: 4
Reputation: 1989
First, just use models.DateTimeField(auto_now_add=True)
Edited:
Second, use get_queryset
method:
class ItemArchive(ArchiveIndexView):
date_field = 'publish_date'
def get_queryset(self):
return Item.objects.published()
Upvotes: 0
Reputation: 16806
I believe this is caused by your view defining queryset = Item.objects.published()
as a class variable. This line will be executed once, when your ItemArchive
class is initially imported. You should move that line into a method where it will be executed each time a view is called.
Upvotes: 14