Merge branch 'feature/bulk_user_import' into development

This commit is contained in:
Roberto Rosario
2012-01-27 02:27:21 -04:00
5 changed files with 111 additions and 4 deletions

View File

@@ -0,0 +1,83 @@
from __future__ import absolute_import
import csv, os, sys
from optparse import make_option
from django.core.management.base import BaseCommand, CommandError, LabelCommand
from django.utils.simplejson import loads, dumps
from django.contrib.auth.models import User
from django.db.utils import IntegrityError
def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
# csv.py doesn't do Unicode; encode temporarily as UTF-8:
csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
dialect=dialect, **kwargs)
for row in csv_reader:
# decode UTF-8 back to Unicode, cell by cell:
yield [unicode(cell, 'utf-8') for cell in row]
def utf_8_encoder(unicode_csv_data):
for line in unicode_csv_data:
yield line.encode('utf-8')
class Command(LabelCommand):
args = '<filename>'
help = 'Import users from a CSV file with the field order: username, firstname, lastname, email.'
option_list = LabelCommand.option_list + (
make_option('--noinput', action='store_false', dest='interactive',
default=True, help='Do not ask the user for confirmation before '
'starting.'),
make_option('--password', action='store', dest='password',
help='The default password to assign to each new user.'),
make_option('--skip-repeated', action='store_true', dest='skip_repeated',
default=False, help='Don\'t exit if the user already exists.'),
)
def handle_label(self, label, **options):
if not os.access(label, os.R_OK):
raise CommandError("File '%s' is not readable." % label)
if options['password']:
default_password = options['password']
else:
default_password = None
if _confirm(options['interactive']) == 'yes':
print 'Beginning import...'
with open(label, 'rb') as f:
reader = unicode_csv_reader(f)
try:
for row in reader:
print 'Adding: %s' % ', '.join(row)
try:
user = User(
username=row[0],
first_name=row[1],
last_name=row[2],
email=row[3]
)
user.set_password(default_password)
user.save()
except IntegrityError:
print 'Repeated user entry: %s' % ', '.join(row)
if options['skip_repeated']:
print 'Ignoring.'
else:
sys.exit()
except csv.Error, e:
sys.exit('file %s, line %d: %s' % (label, reader.line_num, e))
else:
print 'Finish.'
else:
print 'Cancelled.'
def _confirm(interactive):
if not interactive:
return 'yes'
return raw_input('You have requested to import a number of users from a CSV file.\n'
'Are you sure you want to do this?\n'
'Type \'yes\' to continue, or any other value to cancel: ')

View File

@@ -42,8 +42,11 @@ def user_list(request):
{
'name': _(u'active'),
'attribute': encapsulate(lambda x: two_state_template(x.is_active)),
}
},
{
'name': _(u'has usable password?'),
'attribute': encapsulate(lambda x: two_state_template(x.has_usable_password())),
},
],
'multi_select_as_buttons': True,
},
@@ -82,7 +85,9 @@ def user_add(request):
if request.method == 'POST':
form = UserForm(request.POST)
if form.is_valid():
user = form.save()
user = form.save(commit=False)
user.set_unusable_password()
user.save()
messages.success(request, _(u'User "%s" created successfully.') % user)
return HttpResponseRedirect(reverse('user_set_password', args=[user.pk]))
else:

View File

@@ -97,12 +97,31 @@ follow::
**Optional arguments**
* The ``--noinput`` argument skips confirmation and starts the upload inmediately.
* The ``--noinput`` argument skips confirmation and starts the upload immediately.
* The ``--metadata`` argument allows specifing what metadata will be assigned
to the documents when uploaded.
* And the ``--document_type`` applies a previously defined
document type to the uploaded documents.
Out of process user import
~~~~~~~~~~~~~~~~~~~~~~~~~~
A management command has been added to import a large number users
from a CSV file. The command line options for this feature are as
follow::
$ ./manage.py import_users --noinput --password=welcome123 --skip-repeated user_list.csv
The CSV field order must be: username, first name, last name and email, any other
column after those is ignored.
**Optional arguments**
* The ``--noinput`` argument skips confirmation and starts the import immediately.
* The ``--password`` argument allows specifing what default password will be assigned
to all the new users that are imported.
* The ``--skip-repeated`` tells the importedr to not stop when finding
that a user already exists in the database.
Upgrading from a previous version
=================================