Im trying to write a model Manager to get all entries that is published, and start_date is in the past of now
. The strange thing is if I set the date to a value in the past (1 minute prior), everything works, but if I set the date in the future (1 minute ahead), the object does not show, even if I wait more than 1 minute to test. If I do nothing but restart the server, the entry is shown. But I can't restart the server everytime I publish an entry.
Anyone see what could be wrong with this code? Or could this be done differently?
from django.utils import timezone
now = timezone.now()
def entries_published(queryset):
"""Return only the entries published"""
return queryset.filter(
models.Q(start_publication__lte=now) | \
models.Q(start_publication=None),
models.Q(end_publication__gt=now) | \
models.Q(end_publication=None),
status=PUBLISHED)
class EntryPublishedManager(models.Manager):
"""Manager to retrieve published entries"""
def get_queryset(self):
"""Return published entries"""
return entries_published(
super(EntryPublishedManager, self).get_queryset())
class Entry(models.Model):
title = models.CharField(max_length=255)
slug = models.SlugField(max_length=255)
categories = models.ManyToManyField(Category, related_name='entries', blank=True, null=True)
creation_date = models.DateTimeField(auto_now_add=True)
start_publication = models.DateTimeField(blank=True, null=True, help_text="Date and time the entry should be visible")
end_publication = models.DateTimeField(blank=True, null=True, help_text="Date and time the entry should be removed from the site")
status = models.IntegerField(choices=STATUS_CHOICES, default=DRAFT)
objects = models.Manager()
published = EntryPublishedManager()
My view is like this:
class EntryListView(ListView):
context_object_name = "entry_list"
paginate_by = 20
queryset = Entry.published.all().order_by('-start_publication')
If I move now = timezone.now()
inside the def for entries_published
the CategoryDetail
view gets the correct published entries. Any idea why EntryListView
does not show the correct ones?
Here is my CategoryDetail
view
#View for listing one category with all connected and published entries
class CategoryDetail(ListView):
paginate_by = 20
def get_queryset(self):
self.category = get_object_or_404(Category, slug=self.kwargs['slug'])
return Entry.published.filter(categories=self.category).order_by('-start_publication', 'title')
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super(CategoryDetail, self).get_context_data(**kwargs)
# Add in the category
context['category'] = self.category
return context
If I change my EntryListView
to this:
class EntryListView(ListView):
model = Entry
context_object_name = "news_list"
paginate_by = 20
def get_queryset(self):
return Entry.published.all().order_by('-start_publication')
Everything works. Strange, but I don't care.
Edited: I think your problem is now = timezone.now() is set when you start the application. Define 'now' inside your entries_published method.
Added: I would suggest simplifying your method to see ensure the class method is called and skip the function definition entirely.
class EntryPublishedManager(models.Manager):
"""Manager to retrieve published entries"""
def get_queryset(self):
now = timezone.now()
return Super(EntryPublishedManager, self).get_queryset().filter(
models.Q(start_publication__lte=now) | \
models.Q(start_publication=None),
models.Q(end_publication__gt=now) | \
models.Q(end_publication=None),
status=PUBLISHED)