from django.db import models, connection, transaction def update_fields(self, **kwargs): """ Update selected model fields in the database, but leave the other fields alone. Use this rather than model.save() for performance and data consistency. """ sql = ['UPDATE', connection.ops.quote_name(self._meta.db_table), 'SET'] values = [] for field_name in kwargs: setattr(self, field_name, kwargs[field_name]) field = self._meta.get_field(field_name) value = field.get_db_prep_save(kwargs[field_name]) if isinstance(value, models.Model): value = value.id sql.extend((connection.ops.quote_name(field.column), '=', '%s', ',')) values.append(value) sql.pop(-1) # Remove the last comma sql.extend(['WHERE', 'id', '=', '%s']) values.append(self.id) sql = ' '.join(sql) connection.cursor().execute(sql, values) transaction.commit_unless_managed() update_fields.alters_data = True