Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用批量更新一次更新多个模型对象?_Python_Django_Django Models_Django Views - Fatal编程技术网

Python 如何使用批量更新一次更新多个模型对象?

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

这里,来自前端用户的输入值如下['1'、'2'、'3']。我想用
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循环,但理想情况下,您应该使用正确的数据类型来解决问题,并且只需要一个循环。是的,我认为问题是因为数据类型数组和嵌套循环,但我现在无法从客户端更改它,所以我使用数组。