python - Django 查询集缓存与exists() 和values_list()

标签 python django python-3.x python-2.7 django-models

假设我正在尝试将所有名为 John 的个人资料的名称更改为 Mike

queryset = Profile.objects.filter(name='John')

方法一:

if queryset:
    queryset.update(name='Mike')
    logger.info(f'Updated the following profiles: {queryset.values_list('id', flat=True)}')

方法2:

if queryset.exists():
    queryset.update(name='Mike')
    logger.info(f'Updated the following profiles: {queryset.values_list('id', flat=True)}')

问题:更新名为 John 的所有字段并记录更新的记录 ID 的最有效方法是什么?

最佳答案

方法 1 中,调用 if queryset 计算整个查询集

在方法 2 中,使用 queryset.exists() 进行查询,就像 queryset.update(...) 调用一样.

最有效的方法是完全跳过条件 if 语句,而只调用 queryset.update(...)。调用的返回值将包括已更新的行数,可能为 0

为了测试差异,我们可以使用django.db.connection,它将列出所有已执行的查询以及它们花费的时间。

from django.db import connection, reset_queries

from django.contrib.models import User


def method_1(queryset):
    if queryset:
        queryset.update(first_name="Mike")

def method_2(queryset):
    if queryset.exists():
        queryset.update(first_name="Mike")

def method_3(queryset):
    queryset.update(first_name="Mike")


>>> connection.queries == []  # empty to start
True

>>> method_1(User.objects.all())
>>> [query["time"] for query in connection.queries]
['0.051', '0.126']

>>> reset_queries()

>>> method_2(User.objects.all())
>>> [query["time"] for query in connection.queries]
['0.001', '0.125']

>>> reset_queries()

>>> method_3(User.objects.all())
>>> [query["time"] for query in connection.queries]
['0.122']

如您所见,method_3 仅使用单个查询来执行更新,并且比其他方法更快。

关于python - Django 查询集缓存与exists() 和values_list(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59257680/

相关文章:

python - 使用 Python 处理 Excel 表格

Python-替换列表中的项目仅替换第一个实例,而不是所有实例

django - PyCharm:如何在 Django 中切换到常规 HTML 注释(Ctrl+Slash)

python-3.x - 处理 pyspark 数据框中的空值

python - 我们如何访问列表中的多个字典?

python - 使用 Scrapy 管道而不使用 settings.py 配置

python - 创建函数时出现语法错误

python - 记录分组算法

python - 保存产品和公司后立即保存它们

python - 获取 Django 对象并将其包装在 QuerySet 中返回的函数?