2017-01-19 2 views
2

Я пытаюсь обновить пользователя в базе данных Django.Эффективный способ обновления нескольких полей объекта модели Django

извлечённых данные выглядят следующим образом:

fetched_data = { 
    'id': 1, 
    'first_name': 'John', 
    'last_name': 'Doe', 
    'phone': '+32 12', 
    'mobile_phone': '+32 13', 
    'email': '[email protected]', 
    'username': 'myusername' 
} 

я получить пользователь с этим идентификатором следующим образом:

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() 

работает отлично, но я не хочу делать это для каждой записи, таким образом, я trie d что-то вроде:

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() 

Но это не работает. Любая идея, как я могу обновить пользователя, не делая этого для каждой записи?

ответ

4

Вы можете обновить строку в базе данных без выборки и десериализации; update() может это сделать. Например .:

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 не поддерживает это.

3
setattr(old_user, fetched_data_key, fetched_data['fetched_data_key']) 
5

Даже проще, если вы используете .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 объекта, столбцы которой присутствуют в виде ключ к fetched_data dict. Поскольку вы вызываете фильтр на pk, он всегда будет возвращать одну запись.

Смежные вопросы