我正在使用Django。我在为新闻/类别模型缓存QuerySets时遇到了一些问题:
class Category(models.Model):
title = models.CharField(max_length=60)
slug = models.SlugField(unique=True)
class PublishedArticlesManager(models.Manager):
def get_query_set(self):
return super(PublishedArticlesManager, self).get_query_set() \
.filter(published__lte=datetime.datetime.now())
class Article(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length=60)
slug = models.SlugField(unique = True)
story = models.TextField()
author = models.CharField(max_length=60, blank=True)
published = models.DateTimeField(
help_text=_('Set to a date in the future to publish later.'))
created = models.DateTimeField(auto_now_add=True, editable=False)
updated = models.DateTimeField(auto_now=True, editable=False)
live = PublishedArticlesManager()
objects = models.Manager()
注意 - 我删除了一些字段以节省复杂性......
上面有一些(相关的)问题。
首先,当我通过Article.live.all()在我的视图中查询LIVE对象时,如果我反复刷新页面,我可以看到(在MYSQL日志中)相同的数据库查询,其中的日期完全相同子句 - 即 - 在编译时而不是运行时评估datetime.datetime.now()。我需要在运行时评估日期。
其次,当我在Category对象上使用articles_set方法时,这看起来工作正常 - 每次查询运行时查询中使用的日期时间都会更改 - 我再次在日志中看到这一点。但是,我不太清楚为什么会这样,因为我的代码中没有任何内容可以说articles_set查询应该仅返回LIVE条目!?
最后,为什么没有这个被缓存?
如何正确使用正确的时间?有人可以解释为什么后一种设置似乎有用吗?
由于 杰
P.S - 下面的数据库查询,请注意日期变化。
SELECT LIVE ARTICLES,查询#1:
SELECT `news_article`.`id`, `news_article`.`category_id`, `news_article`.`title`, `news_article`.`slug`, `news_article`.`teaser`, `news_article`.`summary`, `news_article`.`story`, `news_article`.`author`, `news_article`.`published`, `news_article`.`created`, `news_article`.`updated` FROM `news_article` WHERE `news_article`.`published` <= '2011-05-17 21:55:41' ORDER BY `news_article`.`published` DESC, `news_article`.`slug` ASC;
SELECT LIVE ARTICLES,查询#1:
SELECT `news_article`.`id`, `news_article`.`category_id`, `news_article`.`title`, `news_article`.`slug`, `news_article`.`teaser`, `news_article`.`summary`, `news_article`.`story`, `news_article`.`author`, `news_article`.`published`, `news_article`.`created`, `news_article`.`updated` FROM `news_article` WHERE `news_article`.`published` <= '2011-05-17 21:55:41' ORDER BY `news_article`.`published` DESC, `news_article`.`slug` ASC;
CATEGORY SELECT ARTICLES,查询#1:
SELECT `news_article`.`id`, `news_article`.`category_id`, `news_article`.`title`, `news_article`.`slug`, `news_article`.`teaser`, `news_article`.`summary`, `news_article`.`story`, `news_article`.`author`, `news_article`.`published`, `news_article`.`created`, `news_article`.`updated` FROM `news_article` WHERE (`news_article`.`published` <= '2011-05-18 21:21:33' AND `news_article`.`category_id` = 1 ) ORDER BY `news_article`.`published` DESC, `news_article`.`slug` ASC;
CATEGORY SELECT ARTICLES,查询#1:
SELECT `news_article`.`id`, `news_article`.`category_id`, `news_article`.`title`, `news_article`.`slug`, `news_article`.`teaser`, `news_article`.`summary`, `news_article`.`story`, `news_article`.`author`, `news_article`.`published`, `news_article`.`created`, `news_article`.`updated` FROM `news_article` WHERE (`news_article`.`published` <= '2011-05-18 21:26:06' AND `news_article`.`category_id` = 1 ) ORDER BY `news_article`.`published` DESC, `news_article`.`slug` ASC;
答案 0 :(得分:0)
您应该查看conditional view processing。
def latest_entry(request, article_id):
return Article.objects.latest("updated").updated
@conditional(last_modified_func=latest_entry)
def view_article(request, article_id)
your view code here
这应该缓存页面而不是每次都重新加载新版本。
我怀疑如果你想在运行时处理now(),你应该使用raw sql。我认为这将解决编译/运行时问题。
class PublishedArticlesManager(models.Manager):
def get_query_set(self):
return super(PublishedArticlesManager, self).get_query_set() \
.raw("SELECT * FROM news_article WHERE published <= CURRENT_TIMESTAMP")
请注意,这会返回一个RawQuerySet,它可能与普通的QuerySet有点不同
答案 1 :(得分:0)
我现在已经解决了这个问题。看来问题是Article.live.all()返回的查询集正在我的urls.py中缓存!我使用的是基于函数的泛型视图:
url(r'^all/$', object_list, {
'queryset' : Article.live.all(),
}, 'news_all'),
我现在已将此更改为使用基于类的方法,如最新的Django文档中所述:
url(r'^all/$', ListView.as_view(
model=Article,
), name="news_all"),
现在按预期工作 - 通过指定模型属性而不是queryset属性,查询是QuerySet是在编译时而不是运行时创建的。