Python Django模型对象多字段更新的有效方法

Python Django模型对象多字段更新的有效方法,python,django,Python,Django,我正在尝试更新Django数据库中的用户 获取的数据如下所示: fetched_data = { 'id': 1, 'first_name': 'John', 'last_name': 'Doe', 'phone': '+32 12', 'mobile_phone': '+32 13', 'email': 'myemail@hotmail.com', 'username': 'myusername' } old_user.u

我正在尝试更新Django数据库中的用户

获取的数据如下所示:

fetched_data = {
     'id': 1,
     'first_name': 'John',
     'last_name': 'Doe',
     'phone': '+32 12',
     'mobile_phone': '+32 13',
     'email': 'myemail@hotmail.com',
     'username': 'myusername'
}
old_user.username = fetched_data['username']
old_user.first_name = fetched_data['first_name']
......
old_user.save()
我获得具有此id的用户,如下所示:

old_user = User.objects.get(pk=fetched_data['id'])
如果我按如下方式更新用户:

fetched_data = {
     'id': 1,
     'first_name': 'John',
     'last_name': 'Doe',
     'phone': '+32 12',
     'mobile_phone': '+32 13',
     'email': 'myemail@hotmail.com',
     'username': 'myusername'
}
old_user.username = fetched_data['username']
old_user.first_name = fetched_data['first_name']
......
old_user.save()
它工作得很好,但我不想对每一张唱片都这样做,因此我尝试了以下方法:

for fetched_data_key in fetched_data:
    old_user.fetched_data_key = fetched_data['fetched_data_key']
    //old_user[fetched_data_key] = fetched_data['fetched_data_key'] --- I tried this way to
    old_user.save()
但这不起作用。您知道我如何更新用户而不必对每个记录都进行更新吗?

如果您使用object方法,则更简单:

setattr(old_user, fetched_data_key, fetched_data['fetched_data_key'])
my_id = fetched_data.pop('id')  # remove 'id' from `fetch_data`
                                # as it is not supposed to be updated

User.objects.filter(pk=my_id).update(**fetched_data)
#          unpack the content of `dict` ^

它将解压
fetched_数据
dict的内容,并将更新
User
对象中的记录,这些记录的列作为
fetched_数据
dict的键出现。由于您正在调用
pk
上的过滤器,它将始终返回单个记录。

您可以更新数据库中的一行,而无需获取和反序列化它;我能做到。例如:

User.objects.filter(id=data['id']).update(email=data['email'], phone=data['phone'])
这将发出一条SQL
update
语句,比您文章中的代码快得多。它永远不会获取数据,也不会浪费时间创建
用户
对象


但是,您不能将一大堆更新数据发送到SQL数据库,并要求它一次性将其映射到不同的行。如果您需要快速完成这样的大规模更新,最好的办法可能是将数据插入单独的表中,然后再进行更新。据我所知,Django ORM不支持这一点

如果使用
.update
则会出现问题,因为它不会发出后保存前保存信号,因此如果要在任何数据更改上使用任何信号,则
用户.objects.filter(pk=获取的数据['id'])。update(**kwargs)
将不起作用

因此,您可以使用
setattr()
更新字段,然后
.save
将保存该行,这将更新该行并发出信号

old_user = User.objects.get(pk=fetched_data['id'])
for key, value in fetched_data.iteritems():
    setattr(old_user, key, value)
old_user.save()
黑引号

def更新_块(请求,id):


如果我只需要更新queryset中的一个对象,该怎么办?“pk”是Django模型中的唯一键。基于它进行筛选时,将返回一个仅包含一个对象的查询集。问题是我没有使用“pk”@brainLoop:默认情况下,“pk”引用Django模型的主键列。@Anonymous我所做的与您解释的完全相同。记录已更新,但“我的已更新位置(现在自动)”字段未更新。可能是因为我们没有执行
Obj.save()
。创建对象时,我知道您可以执行类似
e=User(**data)
的操作。这对更新有用吗?@djangoblockschain:可能有用,但它会破坏这个答案的目的。其思想是不要为每个要更新的DB记录创建ORM模型对象。它真的会降低性能。我最后做了
User.objects.filter(id=data['id']).update(**data)
,所以它只更新每个字段,而不是指定单个字段。如果我的问题让人困惑,很抱歉。嗨,欢迎来到堆栈溢出!请坐飞机。感谢您提供了答案,但是您是否也可以添加关于代码如何解决问题的解释?如果您需要格式方面的帮助,请参阅。这是目前为止最好的方法。在所有大中型Django项目中,信号无处不在;你不会想修补它们的