在update_or_create
的kwargs过滤器中有没有使用列表的方法?
这是我的模特:
class Partner:
...
class MyClassB:
partner = models.OnetoOneField(Partner, related_name='some_name')
....
我尝试使用for循环,但效果很好。
# partners = list of queryset objects.
for partner in partners:
MyClassB.objects.update_or_create(partner=partner, defaults=
{'name': None})
该操作被非常频繁地使用,我正在考虑优化此update_or_create。有什么办法可以一次更新所有合作伙伴?像这样:
MyClassB.objects.update_or_create(partner__in=[partners], defaults={'name': None})
此代码是API的一部分,每5秒将有1000个合作伙伴点击该代码。而且我想避免在这里使用for循环的额外开销。有什么优化的方法吗?
答案 0 :(得分:1)
MyClassB.objects.update_or_create(partner__in=[i.pk for i in Partner.objects.all()], defaults={'name': None})
您可以在同一行中使用此列表理解功能。或创建列表并传递到quesyset
partners = []
partner = Partner.objects.all() // or some filter
for i in partner:
partners.append(i.pk)
MyClassB.objects.update_or_create(partner__in=partners, defaults={'name': None})
答案 1 :(得分:0)
据我所知,update_or_create旨在与单个对象一起使用,而不是很多。
但是,在其中,它会搜索数据库是否存在该条目,如果存在,则对其进行更新,否则会创建一个新条目。
由于create_or_update执行了两个查询,因此您可以执行以下操作而没有太多开销:
existing_db_partners = set(MyClassB.objects.filter(partner__in=partners).values_list('id', flat=True))
to_update = [partner
for partner in partners
if partner.id in existing_db_partners]
to_create = [partner
for partner in partners
if partner.id not in existing_db_partners]
我想不出什么快事
注意:这尚未经过测试。