2011-05-18 28 views
2

我正在使用Django。我有一些问题与新闻/分类模型查询集缓存:Django模型管理器活对象问题

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日志中)在同一个数据库查询中,使用完全相同的日期where子句 - 即 - datetime.datetime.now()正在编译时而不是运行时进行评估。我需要在运行时评估日期。

其次,当我在Category对象上使用articles_set方法时,这看起来工作正常 - 查询中使用的日期时间每次运行查询时都会更改 - 我可以在日志中看到这一点。但是,我不太清楚为什么这会起作用,因为我的代码中没有任何内容可以说articles_set查询应该只返回实时条目!?

最后,为什么没有被缓存呢?

任何想法如何使正确的时间一致使用?有人可以解释为什么后者设置似乎工作?

感谢 周杰伦

P.S - 数据库下查询,注意日期变化。

SELECT LIVE文章,查询#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文章,查询#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; 

类别选择文章,查询#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

想一想,我应该使用单个模型管理器并定义多个方法吗? – 2011-05-19 06:47:11

+0

我觉得单独的经理人完全可以接受。 – 2011-05-19 19:50:42

回答

0

我现在已经解决了这个问题,不同的一点。看来问题是由Article.live.all()返回的queryset被缓存在我的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"), 

这现在可以按预期 - 通过指定模型属性而不是查询集属性,查询是在编译时而不是运行时创建的。

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

+0

谢谢Aaron。任何想法为什么通过Category对象选择使用的时间戳是当前日期/时间,而通过Article直接查询使用编译日期/时间? – 2011-05-20 10:34:08