Python变量范围和惰性查询集

时间:2013-04-18 01:42:52

标签: python django django-queryset

我正在使用Django及其开箱即用的ORM。如果有一些模块级变量,它们是否仅在应用程序启动时进行评估?或者,如果在视图中修改了它们,它们是否也会根据每个请求进行评估?一个例子:

from news.models import News

# Module level variables
draft_news = News.objects.filter(status='draft') 
live_news = News.objects.filter(status='prod')

def view(request):
    # outputs 10 an 10, respectively.
    print 'There are %d news objects and %d live objects. Adding a draft article' % (draft_news.count(), live_news.count()) 

    n = News(
        content='This is test content',
        status='draft',
        slug='this-is-a-test3',
        pubdatetime=datetime.now(),
    )
    n.save()

    print '...done. There are %d draft news objects.' % draft_news.count() # 11 objects
    print 'Changing status to live...'

    n.status='prod'
    n.save()

    print 'There are now %d live objects.' % live_news.count() # 11 objects

由于查询集是惰性的,它们是否处于模块级别或视图级别是否重要?我最初在管理命令中测试了上面的代码。

我们假设重构不是一种选择。

其他信息:我有几个共享同一数据库的应用服务器(uWSGI)。似乎模块级变量只有在我重新启动uWSGI进程时才会更改。换句话说,在视图中使用get_object_or_404时,新的News对象返回404。

1 个答案:

答案 0 :(得分:0)

不,它们处于模块级别或视图级别无关紧要。

声明本身不会触发db请求。只有当您要求具体结果(例如计数或开始迭代)时,才会发生实际的数据库命中。

建议将它们保持在视图级别以保持全局命名空间清洁。

<强>更新
.count()给出过时结果的问题与django db query caching有关,而不是懒惰。请考虑this question页面了解变通方法。