我正在尝试更新Django数据库中的用户。
提取的数据如下:
fetched_data = {
'id': 1,
'first_name': 'John',
'last_name': 'Doe',
'phone': '+32 12',
'mobile_phone': '+32 13',
'email': 'myemail@hotmail.com',
'username': 'myusername'
}
我为用户提供了 id ,如下所示:
old_user = User.objects.get(pk=fetched_data['id'])
如果我按如下方式更新用户:
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()
但这不起作用。任何想法如何在不对每条记录进行更新的情况下更新用户?
答案 0 :(得分:13)
您可以更新数据库中的行而无需获取和反序列化它; update()
可以做到。 E.g:
User.objects.filter(id=data['id']).update(email=data['email'], phone=data['phone'])
这将发出一个SQL update
语句,并且比你帖子中的代码快得多。它永远不会获取数据或浪费时间创建User
对象。
但是,您无法将大量更新数据发送到SQL数据库,并要求它一次性将其映射到不同的行。如果你需要一个非常快速的大规模更新,最好的办法是将数据插入一个单独的表中,然后update it form a select
on that table。据我所知,Django ORM不支持这一点。
答案 1 :(得分:12)
如果使用.update()
对象的QuerySet
方法,则更简单:
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_data
dict的内容,并将User
对象中的记录更新为{em> key 到fetched_data
dict。由于您在pk
上调用过滤器,因此它将始终返回单个记录。
答案 2 :(得分:5)
setattr(old_user, fetched_data_key, fetched_data['fetched_data_key'])
答案 3 :(得分:0)
如果您使用.update
,则会出现问题,因为它不会发出 post_save 或 pre_save 信号,因此,如果要使用任何信号数据发生任何变化,那么User.objects.filter(pk=fetched_data['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()
答案 4 :(得分:0)
黑引号
def update_block(请求,ID):
a = RentedNumberBlock.objects.get(id=id)
b = RentedNumber.objects.filter(user=request.user)
c = a.rented_number.values_list('id', flat=True)
if request.POST:
update = RentedNumberBlock.objects.get(id=id)
update.name = request.POST['name']
z = dict(request.POST)['rented_number']
y = RentedNumber.objects.filter(id__in=z)
update.rented_number.set(z)
update.save()
return HttpResponseRedirect('/block/')
return render(request, "block/update.html", {"a": a , "b": b, "c": c})