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

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行(限制),SAVE会发出10个单独的数据库更新调用,还是Django"聪明"到只发出一个UPDATE调用?

有没有更有效的方法来实现这个结果?

推荐答案

您可以使用F()个对象来完成此操作.

以下是如何导入F:from django.db.models import F

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

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

虽然您不能对切片查询集进行更新.edit: actually you can...

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

  1. 使用您的过滤并收集主键列表
  2. 对匹配任何主键的非切片查询集执行更新.

获取非分片查询集是难点.我想知道如何使用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个数据库命中.

Database相关问答推荐

TYPO3 OOPS,出现错误!编码:202402180809040864ba5c

Mongo DB使用一对多关系离开JOIN

是否有一个简单的工具可以将 mysql 转换为 postgresql 语法?

主必须包括表的分区位置错误中的所有列?

如果我 for each 用户随机设置 SALT,我如何对他们进行身份验证?

SQLite 如果列存在

Oracle 数据库统计信息应该多久运行一次?

数据库设计:喜欢表?

将实体框架中的字符串列映射到枚举

向表中添加大量索引是否有缺点?

如何决定使用什么 [Sqlite、Realm、CoreData、User-default、JSON 文件] 来存储 iOS 数据?

我应该不断地open()和close() SQL 数据库还是让它保持打开状态?

JavaScript 布尔搜索查询生成器接口库?

在服务器上排序还是在客户端排序?

如何在 Rails 中不启动事务的情况下运行迁移?

删除 PHP 中的所有小数

A QuerySet 按聚合字段值

如何在我的 SQL Server 代理作业(job)中创建一个将运行我的 SSIS 包的步骤?

一个表可以有两个外键吗?

如何在文件系统中存储图像