Simplified student import process

This commit is contained in:
Claude Paroz 2016-01-19 10:27:53 +01:00
parent 7d45cd0047
commit 03f45f0785
5 changed files with 89 additions and 8 deletions

View file

@ -1,8 +1,29 @@
from django import forms
from django.conf import settings
from tabimport import FileFactory, UnsupportedFileFormat
from .models import Section, Period
class StudentImportForm(forms.Form):
upload = forms.FileField(label="Fichier des étudiants")
def clean_upload(self):
f = self.cleaned_data['upload']
try:
imp_file = FileFactory(f)
except UnsupportedFileFormat as e:
raise forms.ValidationError("Erreur: %s" % e)
# Check needed headers are present
headers = imp_file.get_headers()
missing = set(settings.STUDENT_IMPORT_MAPPING.keys()) - set(headers)
if missing:
raise forms.ValidationError("Erreur: il manque les colonnes %s" % (
", ".join(missing)))
return f
class PeriodForm(forms.Form):
section = forms.ModelChoiceField(queryset=Section.objects.all())
period = forms.ModelChoiceField(queryset=None)

View file

@ -2,12 +2,18 @@ import json
from collections import OrderedDict
from datetime import date, datetime, timedelta
from django.db.models import Count
from django.http import HttpResponse, HttpResponseNotAllowed
from django.shortcuts import get_object_or_404
from django.views.generic import DetailView, TemplateView, ListView
from tabimport import FileFactory
from .forms import PeriodForm
from django.conf import settings
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.db.models import Count
from django.http import HttpResponse, HttpResponseNotAllowed, HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext as _
from django.views.generic import DetailView, FormView, TemplateView, ListView
from .forms import PeriodForm, StudentImportForm
from .models import (Section, Student, Corporation, CorpContact, Period,
Training, Referent, Availability)
@ -197,7 +203,7 @@ def new_training(request):
avail.save()
except Exception as exc:
return HttpResponse(str(exc))
return HttpResponse('OK')
return HttpResponse(b'OK')
def del_training(request):
""" Delete training and return the referent id """
@ -209,6 +215,44 @@ def del_training(request):
return HttpResponse(json.dumps({'ref_id': ref_id}), content_type="application/json")
class StudentImportView(FormView):
template_name = 'student_import.html'
form_class = StudentImportForm
def form_valid(self, form):
try:
imp_file = FileFactory(form.cleaned_data['upload'])
created, modified = self.import_data(imp_file)
except Exception as e:
if settings.DEBUG:
raise
messages.error(self.request, _("The import failed. Error message: %s") % e)
else:
messages.info(self.request, _("Created objects: %(cr)d, modified objects: %(mod)d") % {
'cr': created, 'mod': modified})
return HttpResponseRedirect(reverse('admin:index'))
def import_data(self, up_file):
""" Import Student data from uploaded file. """
mapping = settings.STUDENT_IMPORT_MAPPING
rev_mapping = {v: k for k, v in mapping.items()}
obj_created = obj_modified = 0
for line in up_file:
defaults = dict((val, line[key]) for key, val in mapping.items() if val != 'ext_id')
defaults = Student.prepare_import(defaults)
obj, created = Student.objects.get_or_create(
ext_id=line[rev_mapping['ext_id']], defaults=defaults)
if not created:
for key, val in defaults.items():
setattr(obj, key, val)
obj.save()
obj_modified += 1
else:
obj_created += 1
#FIXME: implement arch_staled
return obj_created, obj_modified
EXPORT_FIELDS = [
('Prénom', 'student__first_name'), ('Nom', 'student__last_name'),
('ID externe', 'student__ext_id'),