当前位置:  开发笔记 > 编程语言 > 正文

Django:将博客条目视图增加一个.这有效吗?

如何解决《Django:将博客条目视图增加一个.这有效吗?》经验,为你挑选了2个好方法。

我在索引视图中有以下代码.

latest_entry_list = Entry.objects.filter(is_published=True).order_by('-date_published')[:10]
for entry in latest_entry_list:
    entry.views = entry.views + 1
    entry.save()

如果初始查询返回了十行(限制),那么保存问题10是否会更新对数据库的更新调用,或者Django是否"足够聪明"以仅发出一次更新调用?

是否有更有效的方法来实现这一结果?



1> Tom Viner..:

您可以使用F()对象.

以下是您导入的方式F:from django.db.models import F

Django 1.1中的新功能.
调用更新还可以使用F()对象根据模型中另一个字段的值更新一个字段.这对于基于其当前值递增计数器特别有用.

Entry.objects.filter(is_published=True).update(views=F('views')+1)

虽然你无法对切片查询集进行更新... 编辑:实际上你可以......

这可以在django ORM中完全完成.您需要两个SQL查询:

    进行过滤并收集主键列表

    对与任何主键匹配的非切片查询集进行更新.

获取非切片查询集是很难的.我想知道使用in_bulk但返回字典,而不是查询集.人们通常会使用Q objects复杂的OR类型查询,这样可以工作,但pk__in工作更简单.

latest_entry_ids = Entry.objects.filter(is_published=True)\
                                      .order_by('-date_published')
                                      .values_list('id', flat=True)[:10]  
non_sliced_query_set = Entry.objects.filter(pk__in=latest_entry_ids)  
n = non_sliced_query_set.update(views=F('views')+1)  
print n or 0, 'items updated'

由于django懒惰地执行查询的方式,这导致只有2个数据库命中,无论更新了多少项.



2> Jeff Bauer..:

您可以在单个事务中处理更新,这可以显着提高性能.使用单独的函数,用@ transaction.commit_manually装饰.

@transaction.commit_manually
def update_latest_entries(latest_entry_list):
    for entry in latest_entry_list:
        entry.views += 1
        entry.save()
    transaction.commit()


我已经实现了这一点,虽然我还没有注意到任何速度提升,但你还是给了我一些新的东西 - 谢谢!
推荐阅读
mylvfamily
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有