Django模型管理器实时对象问题

时间:2011-05-18 21:22:29

标签: django django-models

我正在使用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;

2 个答案:

答案 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是在编译时而不是运行时创建的。