Python 如何使用批量更新一次更新多个模型对象?
这里,来自前端用户的输入值如下['1'、'2'、'3']。我想用Python 如何使用批量更新一次更新多个模型对象?,python,django,django-models,django-views,Python,Django,Django Models,Django Views,这里,来自前端用户的输入值如下['1'、'2'、'3']。我想用bulk\u update一次更新多个对象,我试着这样做,但这给了我这个错误 ValueError:所有bulk\u update()对象必须设置主键。 用这种类似的方法,我用bulk\u create方法创建了对象,这种方法工作得很好,但用bulk\u update它不工作 这里我想一次更新多个具有不同值的模型对象? class PVariant(models.Model): name = models.CharField
bulk\u update
一次更新多个对象,我试着这样做,但这给了我这个错误
ValueError:所有bulk\u update()对象必须设置主键。
用这种类似的方法,我用bulk\u create
方法创建了对象,这种方法工作得很好,但用bulk\u update
它不工作
这里我想一次更新多个具有不同值的模型对象?
class PVariant(models.Model):
name = models.CharField(max_length=255)
product = models.ForeignKey(Product, on_delete=models.CASCADE)
....
#views
quantity = request.POST.getlist('quantity')
#['1','2','3']
names = request.POST.getlist('names')
fields = ['name', 'price', 'quantity'..]
params = zip(names, quantity, weight,..)
variants = [PVariant(name=param[0],sku=param[1], quantity=param[2], weight=param[3],
product=product) for param in params]
PVariant.objects.bulk_update(variants, fields)
编辑:
从客户端,我在视图中获取这种类型的数据
['name1', 'name2'] names
['12', '1213.0'] field1
['12.0', '12.0'] field2
['1244', '1244'] field3
['11', '11'] field4
['12.0', '12.0'] field5
更新之前,应首先保存所有
PVariant
对象(调用save
方法)。
比如:
variants = []
for param in params:
inst = PVariant(display_name=param[0],sku=param[1], quantity=param[2], weight=param[3], product=product)
inst.save()
variants.append(inst)
解决方案
这可以通过两个查询实现,而不考虑需要更新的变体数量
您只需要在客户端对数据进行适当的索引,以便确定哪些更新应用于服务器端的哪个字段
pvs = PVariant.objects.filter(id__in=pvs_indexed_by_id.keys())
for pv in pvs:
data = pvs_indexed_by_id[pv.id]
pv.name = data[“name”]
...
PVariant.objects.bulk_update(pvs, [“name”, ...])
如果无法修改数据形状客户端,只需在执行上述代码之前清理数据即可:
fields = (“name”, “field1”, ...)
data = {}
for i, field enumerate(request.POST):
data[fields[i]] = field[i]
这不是创建了一个新的对象而不是更新吗?不是。尝试在Django shell中创建
PVariant
对象,就像在代码中那样,然后不调用save
,打印它的id
——它将是None
,因为对象实际上还没有存储在数据库中。当您需要使用一些数据启动记录,然后在实际保存之前进行一些相关修改时,可以使用此选项。由于使用类似的过程,bulk\u-create
工作正常,因此bulk\u-create
会创建新对象,但会将其保存到数据库中吗?对象是否分配了id
?bulk\u update
不允许使用其他选项,因为它需要已存储的记录来执行更新,而不是bulk\u create
。避免在循环中逐个创建记录,因为这最终会成为一个n+1问题。你在索引什么参数,sku?您需要按请求中包含的唯一标识符对数据进行索引,以确定哪些行需要哪些更新。我已根据您的问题中提供的其他信息更新了我的答案是否有嵌套for循环的解决方案?我希望尽可能在视图上处理它。@D\P使用嵌套for循环您想做什么?没必要。您需要在客户端修改表单的数据形状,以提交哈希而不是数组。数组是用于此问题的不正确数据类型。然而,若您被迫使用数组,则必须在视图中预处理表单,以便将数据形状从数组修改为哈希。您可以通过创建索引:field_name(即:0:“name”)的散列单独的散列表来完成此操作,然后代替pv.name=data[“name”],您可以执行pv.getattr(index_to_field_map[i])=data[i],其中i是for循环的索引源。@D\P我提供的示例适用于视图或模型。为了便于维护和单元测试,您的大多数业务逻辑都应该放在模型中,但根据应用程序的复杂性和维护方面的考虑,您只需将其放在视图中即可。@D_P在任何一种情况下都不需要嵌套循环,最多可以有两个for循环,但理想情况下,您应该使用正确的数据类型来解决问题,并且只需要一个循环。是的,我认为问题是因为数据类型数组和嵌套循环,但我现在无法从客户端更改它,所以我使用数组。