假设我正在尝试将所有名为 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/