Unpublish an article on a specific date in django
I have a simple article model with pub_date field and a unpublish_date field.
Is there any way to automagically set my is_published field to False when the unpublish_date is in the past?
class Article(models.Model):
title = models.CharField(max_length=500)
post = models.TextField(blank=Tr开发者_如何学Pythonue, null=True,)
pub_date = models.DateTimeField(default=datetime.datetime.now)
unpublish_date = models.DateTimeField(blank=True, null=True)
is_published = models.BooleanField(default=True,)
You can simply factor this unpublish_date
into your queries, for example:
articles_to_show = Articles.objects.filter(is_published=True,
unpublish_date__gt=datetime.date.today())
This is likely to make your code more complicated, though. You'd have to rewrite all your queries to be aware of the unpublish_date
.
Cron works for this sort of thing but is only good for changing things in large batches once or a few times a day. It doesn't scale well when you have a large batch of tasks to do or want more fine-grained scheduling.
If running a task via cron once per day is sufficient, do that. It might be worth investigating more advanced options such as message queues, though.
To make a scheduled task which will run at a precise time (provided a worker is available), I would use Celery.
from celery.decorators import task
@task
def unpublish(article_pk):
article = Article.objects.get(pk=article_pk)
article.is_published = False
article.save()
# Unpublish article in exactly 7 days from now
from datetime import datetime, timedelta
unpublish.apply_async([article.pk], eta=datetime.now() + datetime.timedelta(7))
I don't think it's possible without a bit of custom code… But that custom code is pretty simple:
def save(self, *args, **kwargs):
if self.unpublished_date < datetime.now():
self.is_published = True
super(Article, self).save(*args, **kwargs)
(of course, make sure you're doing the correct timezone conversion on self.unpublished_date
, if that applies…)
It looks like you need to create some scheduled job that will run on some time interval, check for articles ready to be unpublished and unpublish them.
For such cases I do following things:
- create custom manage.py command that will do your logic. In this case it will be looking for the articles that can be unpublished and change their flag to
unpublished
- set up
cron
to launch this command every X minutes/hours
You can also use djnago-chronograph - this app helps to manage over scheduled tasks in your application.
Using the snippet: http://djangosnippets.org/snippets/838/ solved most of my problem! But now I have come across a new problem.
Im using the fantastic django-template-utils to display the app on every web-page.
If I do this:
objects = ActiveManager(from_date='pub_date', to_date='unpublish_date')
I get only the active objects, but in then they disapear from admin also. Do anyone know if there is some way to get django-templates-utils to use a custom modelManager, instead of the standard one? Or is there a way to use a modelmanager that hides un-active post on the front-end, but will display them in admin?
精彩评论