From b95a856904a907be02c28daceab97e42ab00cfb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Norman=20J=C3=A4ckel?= Date: Sat, 11 Jan 2014 21:56:19 +0100 Subject: [PATCH] Added form field for multiple creation of new participants. Fixed #178. --- CHANGELOG | 1 + openslides/participant/forms.py | 7 ++++ .../templates/participant/overview.html | 1 + .../participant/user_form_multiple.html | 28 ++++++++++++++++ openslides/participant/urls.py | 4 +++ openslides/participant/views.py | 32 +++++++++++++++++-- tests/participant/test_views.py | 11 +++++++ 7 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 openslides/participant/templates/participant/user_form_multiple.html diff --git a/CHANGELOG b/CHANGELOG index c5ea97e67..2b4ce95e3 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -10,6 +10,7 @@ Version 1.6 (unreleased) Participants: - Disabled widgets by default. +- Added form field for multiple creation of new participants. Files: - Enabled update and delete view for uploader refering to his own files. Other: diff --git a/openslides/participant/forms.py b/openslides/participant/forms.py index 4724c8f2b..34c844af3 100644 --- a/openslides/participant/forms.py +++ b/openslides/participant/forms.py @@ -36,6 +36,13 @@ class UserCreateForm(CssClassMixin, forms.ModelForm): return cleaned_data +class UserMultipleCreateForm(forms.Form): + participants_block = forms.CharField( + widget=forms.Textarea, + label=ugettext_lazy('Participants'), + help_text=ugettext_lazy('Use one line per participant for its name (first name and last name).')) + + class UserUpdateForm(UserCreateForm): """ Form to update an user. It raises a validation error, if a non-superuser diff --git a/openslides/participant/templates/participant/overview.html b/openslides/participant/templates/participant/overview.html index 210d4a152..670423b0c 100644 --- a/openslides/participant/templates/participant/overview.html +++ b/openslides/participant/templates/participant/overview.html @@ -21,6 +21,7 @@ {% if perms.participant.can_manage_participant %} {% trans "New" %} + {% trans 'New multiple' %} {% trans "Groups" %} {% trans 'Import' %} {% endif %} diff --git a/openslides/participant/templates/participant/user_form_multiple.html b/openslides/participant/templates/participant/user_form_multiple.html new file mode 100644 index 000000000..fff47d803 --- /dev/null +++ b/openslides/participant/templates/participant/user_form_multiple.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} + +{% load i18n %} + +{% block title %} + {% trans 'New multiple participants' %} – {{ block.super }} +{% endblock %} + +{% block content %} +

+ {% trans 'New multiple participants' %} + + + {% trans 'Back to overview' %} + + +

+
{% csrf_token %} + {% include 'form.html' %} +

+ {% include 'formbuttons_save.html' %} + + {% trans 'Cancel' %} + +

+ * {% trans 'required' %} +
+{% endblock %} diff --git a/openslides/participant/urls.py b/openslides/participant/urls.py index 8d5bbbbd5..dcacd8e6b 100644 --- a/openslides/participant/urls.py +++ b/openslides/participant/urls.py @@ -15,6 +15,10 @@ urlpatterns = patterns( views.UserCreateView.as_view(), name='user_new'), + url(r'^new_multiple/$', + views.UserMultipleCreateView.as_view(), + name='user_new_multiple'), + url(r'^(?P\d+)/$', views.UserDetailView.as_view(), name='user_view'), diff --git a/openslides/participant/views.py b/openslides/participant/views.py index accfbb909..bf0fdb415 100644 --- a/openslides/participant/views.py +++ b/openslides/participant/views.py @@ -3,6 +3,7 @@ from django.contrib import messages from django.contrib.auth.decorators import login_required from django.contrib.auth.forms import PasswordChangeForm +from django.contrib.auth.hashers import make_password from django.contrib.auth.views import login as django_login from django.core.urlresolvers import reverse from django.shortcuts import redirect @@ -18,8 +19,8 @@ from openslides.utils.views import (CreateView, DeleteView, DetailView, RedirectView, SingleObjectMixin, UpdateView) from .api import gen_password, gen_username, import_users -from .forms import (GroupForm, UserCreateForm, UserImportForm, UsersettingsForm, - UserUpdateForm) +from .forms import (GroupForm, UserCreateForm, UserMultipleCreateForm, UserImportForm, + UsersettingsForm, UserUpdateForm) from .models import get_protected_perm, Group, User from .pdf import participants_to_pdf, participants_passwords_to_pdf @@ -91,6 +92,33 @@ class UserCreateView(CreateView): self.object.groups.add(registered) +class UserMultipleCreateView(FormView): + """ + View to create multiple users at once using a big text field. + """ + permission_required = 'participant.can_manage_participant' + template_name = 'participant/user_form_multiple.html' + form_class = UserMultipleCreateForm + success_url_name = 'user_overview' + + def form_valid(self, form): + # TODO: Use bulk_create after rework of participant.models.User + for number, line in enumerate(form.cleaned_data['participants_block'].splitlines()): + names_list = line.split() + first_name = ' '.join(names_list[:-1]) + last_name = names_list[-1] + username = gen_username(first_name, last_name) + default_password = gen_password() + User.objects.create( + username=username, + first_name=first_name, + last_name=last_name, + default_password=default_password, + password=make_password(default_password, '', 'md5')) + messages.success(self.request, _('%(number)d users successfully created.') % {'number': number + 1}) + return super(UserMultipleCreateView, self).form_valid(form) + + class UserUpdateView(UpdateView): """ Update an existing participant. diff --git a/tests/participant/test_views.py b/tests/participant/test_views.py index 13e7c1800..61cec524a 100644 --- a/tests/participant/test_views.py +++ b/tests/participant/test_views.py @@ -28,6 +28,17 @@ class UserViews(TestCase): response = self.client.post('/participant/new/', {'first_name': 'test_name_ho8hui2niz4nohSupahb'}) self.assertRedirects(response, '/participant/') + def test_create_multiple(self): + response = self.client.get('/participant/new_multiple/') + self.assertTemplateUsed(response, 'participant/user_form_multiple.html') + self.assertContains(response, 'New multiple participants') + self.assertEqual(User.objects.count(), 1) + block = ('first_name_ksdjfhkjsdhf75utgeitrten last_name_khonizt958zh8fh\n' + 'first_name_1_bmgnf7z8ru first_name_2_kjc98vivt last_name_dfg76kjkjuibv') + response = self.client.post('/participant/new_multiple/', + {'participants_block': block}) + self.assertEqual(User.objects.count(), 3) + def test_update(self): response = self.client.get('/participant/1/edit/') self.assertTemplateUsed(response, 'participant/edit.html')