Reputation: 1300
I'm developing a blog and I'm using this filter for put online the posts automatically:
geopost_filter = GeoPost.objects.filter(draft=False, publishing_date__lte=timezone.now())
This filter run in local but doesn't run in production. For put online the post that pass from "it will be published in future" to "it is now online" I must restart the server in production.
Why happen this?
I can change the post's status using the draft field without problem, both in local than in production. But it seams not possible to publish automatically a post if it is marked as future post.
EDIT after request from Willem Van Onsem
I use this filter into a view and into an api view.
from django.core.paginator import Paginator
from django.db.models.functions import Now
from django.shortcuts import get_object_or_404, redirect, render
from .models import GeoPost, GeoTag
geopost_filter = GeoPost.objects.filter(
draft=False,
publishing_date__lte=Now()
)
def geotag_single(request, slug_tag):
geotag = get_object_or_404(GeoTag, slug_tag=slug_tag)
geopost_full = geopost_filter.filter(tags=geotag)
paginator = Paginator(geopost_full, 10)
page = request.GET.get("pagina")
geopost_list = paginator.get_page(page)
context = {
"tag": geotag,
"post_list": geopost_list,
}
return render(request, 'geoblog/single_tag.html', context)
apiviews
from rest_framework.decorators import api_view
from rest_framework.response import Response
from geoblog.models import GeoPost
from geoblog.views import geopost_filter
@api_view(["GET"])
def geoblogPost_apiview(request):
if request.method == "GET":
if request.user.is_staff:
objects = GeoPost.objects.all()
else:
objects = geopost_filter
serializer = GeoPostSerializer(objects, many=True)
return Response(serializer.data)
GeoPost is a model that use the PontField together the classical fields of a blog post like title and contents. This is an example:
from django.contrib.gis.db import models
from django.utils import timezone
GeoPost(models.Model):
geom = models.PointField(
blank=True,
null=True,
)
publishing_date = models.DateTimeField(
default=timezone.now,
)
title = models.CharField(
max_length=70,
unique=True,
)
contents = models.TextField()
draft = models.BooleanField()
Maybe the problem is in publishing_date
because I use timezone.now
?
Upvotes: 1
Views: 311
Reputation: 477503
Likely you defined the query once, and reuse it multiple times. As a result the timezone.now
is not updated, and thus the "new" GeoPost
s do not get published.
You can however make use of the database time with a Now
expression [Django-doc]:
from django.db.models.functions import Now
geopost_filter = GeoPost.objects.filter(
draft=False, publishing_date__lte=Now()
)
Here Now
is not converted to the time when you construct the queryset, it uses the time at the database, so you can reuse this queryset.
Another problem is that you make use of a global variable, and thus the results get cached. This means that after making one query, the query is not done again. You can force requerying, for example with .all()
:
@api_view(["GET"])
def geoblogPost_apiview(request):
if request.method == "GET":
if request.user.is_staff:
objects = GeoPost.objects.all()
else:
objects = geopost_filter.all()
serializer = GeoPostSerializer(objects, many=True)
return Response(serializer.data)
Upvotes: 2