Project

General

Profile

« Previous | Next » 

Revision 64438aee

Added by Serghei Mihai almost 9 years ago

import users view(#7065)

View differences:

uauth/organization/forms.py
27 27
class LocalAccountCreateForm(LocalAccountForm):
28 28
    accounts_number = forms.IntegerField(_('Number of accounts to create'), required=False)
29 29
    accounts_number_start = forms.IntegerField(_('First number of multiple accounts'), required=False)
30

  
31

  
32
class UsersImportForm(forms.Form):
33
    users_file = forms.FileField(_('Users file'))
uauth/organization/templates/organization/import_users.html
1
{% extends 'uauth/base.html' %}
2
{% load i18n %}
3

  
4
{% block content %}
5
<form method="post" action="{% url "import-users" organization.slug %}" enctype="multipart/form-data">
6
  {% csrf_token %}
7
  {{ form.as_p }}
8
  <h3>{% trans "Expected file format" %}: CSV</h3>
9
  <ul>
10
    <li>{% trans "5 columns: login, first name, last name, expiration date, password" %}</li>
11
    <li>{% trans "date format: YYYY-MM-DD" %}</li>
12
    <li>{% trans "if empty password, it will be generated" %}</li>
13
    <li>{% trans "if user exists, it will be updated" %}</li>
14
    <li>{% trans "separator: comma" %}</li>
15
    <li>{% trans "encoding: utf-8" %}</li>
16
    <li>{% trans "first line is ignored" %}</li>
17
  </ul>
18
  <p>Example:
19
    <div class="example">
20
      "login", "first name", "last name", "expiration", "password"<br />
21
      "foo", "Foo", "User", "2015-12-31", "secret" <br />
22
      "bar", "User", "Bar", "2015-04-30", ""<br />
23
      "test", "", "", "", ""<br />
24
    </div>
25
  </p>
26
  <p><button name="upload">{% trans "Import" %}</button>
27
</form>
28
{% endblock %}
uauth/organization/templates/organization/users.html
7 7

  
8 8
{% block appbar %}
9 9
<h2>{% trans "Local users" %}</h2>
10
<a href="{% url "import-users" organization.slug %}" rel="popup">{% trans "Import users" %}</a>
10 11
<a href="{% url "create-users" organization.slug %}" rel="popup">{% trans "Create users" %}</a>
11 12
{% endblock %}
12 13

  
uauth/organization/urls.py
6 6
    url(r'^$', manage, name='manage'),
7 7
    url(r'^users/?$', users, name='manage-users'),
8 8
    url(r'^users/create$', create_users, name='create-users'),
9
    url(r'^users/import$', import_users, name='import-users'),
9 10
    url(r'^users/(?P<pk>[\w]+)/$', view_user, name='view-user'),
10 11
    url(r'^users/(?P<pk>[\w]+)/edit$', edit_user, name='edit-user'),
11 12
)
uauth/organization/utils.py
18 18
        return user
19 19
    except:
20 20
        return False
21

  
22
def create_or_update_users(data):
23
    created = 0
24
    updated = 0
25
    for user in data:
26
        try:
27
            account = LocalAccount.objects.get(username=user['username'])
28
            if not user['password']:
29
                del user['password']
30
            account.__dict__.update(user)
31
            account.save()
32
            updated += 1
33
        except LocalAccount.DoesNotExist:
34
            if create_user(user):
35
                created += 1
36
    return created, updated
uauth/organization/views.py
1
import csv
2
import datetime
3

  
1 4
from django.utils.translation import ugettext as _
2 5
from django.core.urlresolvers import reverse_lazy
3
from django.http import HttpResponseRedirect
6
from django.shortcuts import render, redirect
4 7

  
5 8
from django.views.generic.base import TemplateView
6 9
from django.views.generic.list import ListView
7 10
from django.views.generic.edit import FormView, UpdateView
8
from django.views.generic import DetailView
11
from django.views.generic import DetailView, View
9 12
from django.contrib import messages
10 13

  
11 14
from django_tables2 import RequestConfig
12 15

  
13
from .utils import create_user
16
from .utils import create_user, create_or_update_users
14 17
from .models import LocalAccount, Organization
15
from .forms import LocalAccountCreateForm, LocalAccountForm
18
from .forms import LocalAccountCreateForm, LocalAccountForm, UsersImportForm
16 19
from .tables import AccountTable
17 20

  
18 21

  
......
96 99
        if 'delete' in self.request.POST:
97 100
            self.object.delete()
98 101
            messages.info(self.request, _('Account "%s" successfully deleted' % username))
99
            return HttpResponseRedirect(self.get_success_url())
102
            return redirect(self.get_success_url())
100 103
        else:
101 104
            messages.info(self.request, _('Account "%s" successfully updated' % username))
102 105
            return super(UserEditView, self).form_valid(form)
103 106

  
104 107
edit_user = UserEditView.as_view()
108

  
109

  
110
class ImportUsersView(OrganizationMixin, TemplateView):
111
    form_class = UsersImportForm
112
    template_name = 'organization/import_users.html'
113

  
114
    def get_context_data(self, **kwargs):
115
        ctx = super(ImportUsersView, self).get_context_data(**kwargs)
116
        ctx['form'] = self.form_class()
117
        return ctx
118

  
119
    def post(self, request, *args, **kwargs):
120
        form = self.form_class(request.POST, request.FILES)
121
        context = self.get_context_data(**kwargs)
122
        context['form'] = form
123
        if form.is_valid():
124
            data = form.cleaned_data['users_file']
125
            dialect = csv.Sniffer().sniff(data.read(1024))
126
            data.seek(0)
127
            reader = csv.reader(data, dialect)
128
            reader.next()
129
            users = []
130
            for row in reader:
131
                try:
132
                    user = {'username': row[0].strip(),
133
                            'first_name': row[1].strip(),
134
                            'last_name': row[2].strip(),
135
                            'password': row[4].strip(),
136
                            'organization': context['organization']
137
                        }
138
                except IndexError:
139
                    # ignore wrong lines
140
                    continue
141
                try:
142
                    user['expiration_date'] = datetime.datetime.strptime(row[3], '%Y-%m-%d')
143
                except ValueError:
144
                    pass
145
                users.append(user)
146
            created, updated = create_or_update_users(users)
147
            if created:
148
                messages.info(request, _('%s accounts added' % created))
149
            if updated:
150
                messages.info(request, _('%s accounts updated' % updated))
151
            return redirect(self.get_success_url())
152
        else:
153
            return self.render_to_response(context)
154

  
155
import_users = ImportUsersView.as_view()
uauth/static/css/style.css
61 61
.icon-delete:before {
62 62
    content: '\f1f8';
63 63
    margin: 0 3px;
64
}
65

  
66
div.example {
67
    background: #eee;
68
    border: 1px solid #bbb;
69
    font-family: Monospace;
64 70
}

Also available in: Unified diff