summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@proxience.com>2015-05-03 23:21:46 +0200
committerÉtienne Loks <etienne.loks@proxience.com>2015-05-03 23:21:46 +0200
commit274b8d44ccf1f099f2e22b5a6a70f9743b746c1d (patch)
tree9d23175660bb6b6d1adcbcec722bf4ea88f0b818 /ishtar_common
parent40ffb48d6075a14a9591d6a7c83f40ef5afe97e5 (diff)
downloadIshtar-274b8d44ccf1f099f2e22b5a6a70f9743b746c1d.tar.bz2
Ishtar-274b8d44ccf1f099f2e22b5a6a70f9743b746c1d.zip
Interface: create new import, management interface
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/data_importer.py35
-rw-r--r--ishtar_common/forms_common.py13
-rw-r--r--ishtar_common/ishtar_menu.py17
-rw-r--r--ishtar_common/migrations/0027_auto__chg_field_targetkey_target.py313
-rw-r--r--ishtar_common/models.py96
-rw-r--r--ishtar_common/templates/ishtar/form.html13
-rw-r--r--ishtar_common/templates/ishtar/import_list.html47
-rw-r--r--ishtar_common/urls.py5
-rw-r--r--ishtar_common/views.py69
9 files changed, 556 insertions, 52 deletions
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py
index 194a9a5fa..cef98789e 100644
--- a/ishtar_common/data_importer.py
+++ b/ishtar_common/data_importer.py
@@ -21,7 +21,7 @@ import copy, csv, datetime, logging, re, sys
from tempfile import NamedTemporaryFile
from django.contrib.auth.models import User
-from django.db import DatabaseError, IntegrityError
+from django.db import DatabaseError, IntegrityError, transaction
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
@@ -275,12 +275,16 @@ class StrChoiceFormater(Formater):
else:
self.equiv_dict[value] = None
if output == 'db' and self.db_target:
- for missing in missings:
- try:
- q = {'target':self.db_target, 'value':missing}
- models.TargetKey.objects.create(**q)
- except IntegrityError:
- pass
+ from ishtar_common.models import TargetKey
+ for missing in self.missings:
+ q = {'target':self.db_target, 'value':missing}
+ if TargetKey.objects.filter(**q).count():
+ continue
+ with transaction.commit_on_success():
+ try:
+ TargetKey.objects.create(**q)
+ except IntegrityError:
+ pass
def new(self, value):
return
@@ -402,7 +406,8 @@ class StrToBoolean(Formater):
else:
self.dct[value] = None
if output == 'db' and self.db_target:
- for missing in missings:
+ from ishtar_common.models import TargetKey
+ for missing in self.missings:
try:
q = {'target':self.db_target, 'value':missing}
models.TargetKey.objects.create(**q)
@@ -439,7 +444,7 @@ class Importer(object):
def __init__(self, skip_lines=0, reference_header=None,
check_col_num=False, test=False, check_validity=True,
history_modifier=None, output='silent',
- importer_instance=None):
+ import_instance=None):
"""
* skip_line must be set if the data provided has got headers lines.
* a reference_header can be provided to perform a data compliance
@@ -458,14 +463,13 @@ class Importer(object):
self.check_col_num = check_col_num
self.check_validity = check_validity
self.line_format = copy.copy(self.LINE_FORMAT)
- self.importer_instance = importer_instance
- self._initialized = False
+ self.import_instance = import_instance
self._defaults = self.DEFAULTS.copy()
self.history_modifier = history_modifier
self.output = output
if not self.history_modifier:
- if self.importer_instance:
- self.history_modifier = self.importer_instance.user
+ if self.import_instance:
+ self.history_modifier = self.import_instance.user
else:
# import made by the CLI: get the first admin
self.history_modifier = User.objects.filter(
@@ -494,11 +498,10 @@ class Importer(object):
for idx, formater in enumerate(self.line_format):
if formater:
formater.init(vals[idx], output)
- self._initialized = True
- def importation(self, table):
+ def importation(self, table, initialize=True):
self.validity_file = None
- if not self._initialized:
+ if initialize:
self.initialize(table, self.output)
if self.check_validity:
with NamedTemporaryFile(delete=False) as validity_file:
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py
index a229fe319..b6971c4f4 100644
--- a/ishtar_common/forms_common.py
+++ b/ishtar_common/forms_common.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -27,8 +27,8 @@ from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core import validators
+from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.core.mail import send_mail
-from django.core.exceptions import ObjectDoesNotExist
from django.forms.formsets import formset_factory, DELETION_FIELD_NAME
from django.forms.models import BaseModelFormSet
from django.template import Context, RequestContext, loader
@@ -89,6 +89,15 @@ class NewItemForm(forms.Form):
if len(new_choices) == 1:
self.fields[key].initial = [new_choices[0][0]]
+class NewImportForm(forms.ModelForm):
+ class Meta:
+ model = models.Import
+ fields = ('importer_type', 'imported_file', 'skip_lines')
+
+ def save(self, user, commit=True):
+ self.instance.user = user
+ return super(NewImportForm, self).save(commit)
+
class OrganizationForm(NewItemForm):
form_label = _(u"Organization")
associated_models = {'organization_type':models.OrganizationType}
diff --git a/ishtar_common/ishtar_menu.py b/ishtar_common/ishtar_menu.py
index 1dd22bd8a..fdfe60448 100644
--- a/ishtar_common/ishtar_menu.py
+++ b/ishtar_common/ishtar_menu.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2013 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -71,6 +71,19 @@ MENU_SECTIONS = [
'change_own_organization']),
]),
])
- )
+ ),
+ (15, SectionItem('imports', _(u"Imports"),
+ childs=[
+ MenuItem('import', _(u"New import"),
+ model=models.Import,
+ access_controls=['change_import']),
+ MenuItem('import-list', _(u"Current imports"),
+ model=models.Import,
+ access_controls=['change_import']),
+ MenuItem('import-list-old', _(u"Old imports"),
+ model=models.Import,
+ access_controls=['change_import']),
+ ])
+ ),
]
diff --git a/ishtar_common/migrations/0027_auto__chg_field_targetkey_target.py b/ishtar_common/migrations/0027_auto__chg_field_targetkey_target.py
new file mode 100644
index 000000000..d6ea7e10a
--- /dev/null
+++ b/ishtar_common/migrations/0027_auto__chg_field_targetkey_target.py
@@ -0,0 +1,313 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+
+ # Changing field 'TargetKey.target'
+ db.alter_column('ishtar_common_targetkey', 'target_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['ishtar_common.ImportTarget']))
+
+ def backwards(self, orm):
+
+ # Changing field 'TargetKey.target'
+ db.alter_column('ishtar_common_targetkey', 'target_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['ishtar_common.ImporterColumn']))
+
+ models = {
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ 'ishtar_common.arrondissement': {
+ 'Meta': {'object_name': 'Arrondissement'},
+ 'department': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'})
+ },
+ 'ishtar_common.author': {
+ 'Meta': {'object_name': 'Author'},
+ 'author_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.AuthorType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'author'", 'to': "orm['ishtar_common.Person']"})
+ },
+ 'ishtar_common.authortype': {
+ 'Meta': {'object_name': 'AuthorType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'ishtar_common.canton': {
+ 'Meta': {'object_name': 'Canton'},
+ 'arrondissement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Arrondissement']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '30'})
+ },
+ 'ishtar_common.department': {
+ 'Meta': {'ordering': "['number']", 'object_name': 'Department'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
+ 'number': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '3'})
+ },
+ 'ishtar_common.documenttemplate': {
+ 'Meta': {'ordering': "['associated_object_name', 'name']", 'object_name': 'DocumentTemplate'},
+ 'associated_object_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'template': ('django.db.models.fields.files.FileField', [], {'max_length': '100'})
+ },
+ 'ishtar_common.format': {
+ 'Meta': {'object_name': 'Format'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'ishtar_common.formatertype': {
+ 'Meta': {'unique_together': "(('formater_type', 'options', 'many_split'),)", 'object_name': 'FormaterType'},
+ 'formater_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'many_split': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'options': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.globalvar': {
+ 'Meta': {'ordering': "['slug']", 'object_name': 'GlobalVar'},
+ 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'}),
+ 'value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.historicalorganization': {
+ 'Meta': {'ordering': "('-history_date', '-history_id')", 'object_name': 'HistoricalOrganization'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'history_creator_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'history_id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'history_modifier_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'history_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
+ 'history_user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'blank': 'True'}),
+ 'merge_key': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'organization_type_id': ('django.db.models.fields.IntegerField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.import': {
+ 'Meta': {'object_name': 'Import'},
+ 'creation_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'null': 'True', 'blank': 'True'}),
+ 'end_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'error_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'imported_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.ImporterType']"}),
+ 'result_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'seconds_remaining': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'skip_lines': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'state': ('django.db.models.fields.CharField', [], {'default': "'C'", 'max_length': '2'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.IshtarUser']"})
+ },
+ 'ishtar_common.importercolumn': {
+ 'Meta': {'object_name': 'ImporterColumn'},
+ 'col_number': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'columns'", 'to': "orm['ishtar_common.ImporterType']"}),
+ 'regexp_pre_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Regexp']", 'null': 'True', 'blank': 'True'}),
+ 'required': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'ishtar_common.importerdefault': {
+ 'Meta': {'object_name': 'ImporterDefault'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'defaults'", 'to': "orm['ishtar_common.ImporterType']"}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.importerdefaultvalues': {
+ 'Meta': {'object_name': 'ImporterDefaultValues'},
+ 'default_target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'default_values'", 'to': "orm['ishtar_common.ImporterDefault']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
+ 'value': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.importerduplicatefield': {
+ 'Meta': {'object_name': 'ImporterDuplicateField'},
+ 'column': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'duplicate_fields'", 'to': "orm['ishtar_common.ImporterColumn']"}),
+ 'field_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
+ },
+ 'ishtar_common.importertype': {
+ 'Meta': {'object_name': 'ImporterType'},
+ 'associated_models': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_template': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
+ 'users': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['ishtar_common.IshtarUser']", 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.importtarget': {
+ 'Meta': {'object_name': 'ImportTarget'},
+ 'column': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'targets'", 'to': "orm['ishtar_common.ImporterColumn']"}),
+ 'formater_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.FormaterType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'regexp_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Regexp']", 'null': 'True', 'blank': 'True'}),
+ 'target': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.ishtaruser': {
+ 'Meta': {'object_name': 'IshtarUser', '_ormbases': ['auth.User']},
+ 'person': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'ishtaruser'", 'unique': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'user_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True', 'primary_key': 'True'})
+ },
+ 'ishtar_common.itemkey': {
+ 'Meta': {'object_name': 'ItemKey'},
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'importer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Import']", 'null': 'True', 'blank': 'True'}),
+ 'key': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {})
+ },
+ 'ishtar_common.organization': {
+ 'Meta': {'object_name': 'Organization'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}),
+ 'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Organization']"}),
+ 'merge_key': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'organization_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.OrganizationType']"}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.organizationtype': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'OrganizationType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'ishtar_common.person': {
+ 'Meta': {'object_name': 'Person'},
+ 'address': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'address_complement': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'attached_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'members'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['ishtar_common.Organization']"}),
+ 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'merge_candidate': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_candidate_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'merge_exclusion': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'merge_exclusion_rel_+'", 'null': 'True', 'to': "orm['ishtar_common.Person']"}),
+ 'merge_key': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
+ 'person_types': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['ishtar_common.PersonType']", 'symmetrical': 'False'}),
+ 'phone': ('django.db.models.fields.CharField', [], {'max_length': '18', 'null': 'True', 'blank': 'True'}),
+ 'postal_code': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}),
+ 'raw_name': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}),
+ 'surname': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '2', 'null': 'True', 'blank': 'True'}),
+ 'town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'})
+ },
+ 'ishtar_common.persontype': {
+ 'Meta': {'ordering': "('label',)", 'object_name': 'PersonType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'ishtar_common.regexp': {
+ 'Meta': {'object_name': 'Regexp'},
+ 'description': ('django.db.models.fields.CharField', [], {'max_length': '500', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'regexp': ('django.db.models.fields.CharField', [], {'max_length': '500'})
+ },
+ 'ishtar_common.sourcetype': {
+ 'Meta': {'object_name': 'SourceType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'ishtar_common.supporttype': {
+ 'Meta': {'object_name': 'SupportType'},
+ 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
+ },
+ 'ishtar_common.targetkey': {
+ 'Meta': {'unique_together': "(('target', 'value'),)", 'object_name': 'TargetKey'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_set': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'key': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
+ 'target': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'keys'", 'to': "orm['ishtar_common.ImportTarget']"}),
+ 'value': ('django.db.models.fields.TextField', [], {})
+ },
+ 'ishtar_common.town': {
+ 'Meta': {'ordering': "['numero_insee']", 'object_name': 'Town'},
+ 'canton': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Canton']", 'null': 'True', 'blank': 'True'}),
+ 'center': ('django.contrib.gis.db.models.fields.PointField', [], {'srid': '27572', 'null': 'True', 'blank': 'True'}),
+ 'departement': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['ishtar_common.Department']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'numero_insee': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '6'}),
+ 'surface': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'})
+ }
+ }
+
+ complete_apps = ['ishtar_common'] \ No newline at end of file
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 1f059f2f5..b43d3a50c 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -973,11 +973,15 @@ def get_model_fields(model):
"""
fields = {}
options = model._meta
- for field in sorted(options.concrete_fields + options.many_to_many +
- options.virtual_fields):
+ for field in sorted(options.fields):
fields[field.name] = field
return fields
+def import_class(full_path_classname):
+ mods = full_path_classname.split('.')
+ module = import_module('.'.join(mods[:-1]))
+ return getattr(module, mods[-1])
+
class ImporterType(models.Model):
"""
Description of a table to be mapped with ishtar database
@@ -998,22 +1002,19 @@ class ImporterType(models.Model):
def __unicode__(self):
return self.name
- @property
- def importer_class(self):
- name = ''.join(x for x in slugify(self.name).replace('-', ' ').title()
- if not x.isspace())
- OBJECT_CLS = import_module(self.associated_models)
- DEFAULTS = dict((default.keys, default.values)
- for default in self.defaults.all())
+ def get_importer_class(self):
+ OBJECT_CLS = import_class(self.associated_models)
+ DEFAULTS = dict([(default.keys, default.values)
+ for default in self.defaults.all()])
LINE_FORMAT = []
idx = 0
for column in self.columns.order_by('col_number').all():
idx += 1
- while column.order > idx:
+ while column.col_number > idx:
LINE_FORMAT.append(None)
idx += 1
- targets = None
- formater_types = None
+ targets = []
+ formater_types = []
nb = column.targets.count()
if not nb:
LINE_FORMAT.append(None)
@@ -1035,6 +1036,8 @@ class ImporterType(models.Model):
LINE_FORMAT.append(formater)
args = {'OBJECT_CLS':OBJECT_CLS, 'DESC':self.description,
'DEFAULTS':DEFAULTS, 'LINE_FORMAT':LINE_FORMAT}
+ name = str(''.join(x for x in slugify(self.name).replace('-', ' ').title()
+ if not x.isspace()))
newclass = type(name, (Importer,), args)
return newclass
@@ -1050,12 +1053,12 @@ class ImporterDefault(models.Model):
@property
def keys(self):
- return default.target.split('__')
+ return tuple(self.target.split('__'))
@property
def associated_model(self):
field = None
- OBJECT_CLS = import_module(self.importer_type.associated_models)
+ OBJECT_CLS = import_class(self.importer_type.associated_models)
for idx, item in enumerate(self.keys):
if not idx:
field = get_model_fields(OBJECT_CLS)[item]
@@ -1084,9 +1087,17 @@ class ImporterDefaultValues(models.Model):
verbose_name_plural = _(u"Importer - Default values")
def get_value(self):
- model = self.default_target.associated_model
- if not model:
+ parent_model = self.default_target.associated_model
+ if not parent_model:
return self.value
+ fields = get_model_fields(parent_model)
+ target = self.target.strip()
+ if target not in fields:
+ return
+ field = fields[target]
+ if not hasattr(field, 'rel') or not hasattr(field.rel, 'to'):
+ return
+ model = field.rel.to
# if value is an id
try:
return model.objects.get(pk=int(self.value))
@@ -1154,7 +1165,7 @@ class TargetKey(models.Model):
Also temporary used for GeneralType to point missing link before adding
them in ItemKey table
"""
- target = models.ForeignKey(ImporterColumn, related_name='keys')
+ target = models.ForeignKey(ImportTarget, related_name='keys')
key = models.TextField(_(u"Key"), blank=True, null=True)
value = models.TextField(_(u"Value"))
is_set = models.BooleanField(_(u"Is set"), default=False)
@@ -1174,7 +1185,7 @@ TARGET_MODELS = [
('archaeological_operations.models.Period', _(u"Period")),
]
-TARGET_MODELS_KEYS = (tm[0] for tm in TARGET_MODELS)
+TARGET_MODELS_KEYS = [tm[0] for tm in TARGET_MODELS]
IMPORTER_TYPES = (
('IntegerFormater', _(u"Integer")),
@@ -1226,7 +1237,7 @@ class FormaterType(models.Model):
def get_formater_type(self, target):
if self.formater_type not in IMPORTER_TYPES_DCT.keys():
return
- kwargs = {'target':target}
+ kwargs = {'db_target':target}
if self.many_split:
kwargs['many_split'] = self.many_split
if self.formater_type == 'TypeFormater':
@@ -1236,18 +1247,18 @@ class FormaterType(models.Model):
if self.options in dir():
model = dir()[self.options]
else:
- model = import_module(self.options)
+ model = import_class(self.options)
return TypeFormater(model, **kwargs)
elif self.formater_type == 'IntegerFormater':
return IntegerFormater(**kwargs)
elif self.formater_type == 'FloatFormater':
return FloatFormater(**kwargs)
- elif self.format_type == 'UnicodeFormater':
+ elif self.formater_type == 'UnicodeFormater':
try:
return UnicodeFormater(int(self.options.strip()), **kwargs)
except ValueError:
return
- elif self.format_type == 'DateFormater':
+ elif self.formater_type == 'DateFormater':
return DateFormater(self.options, **kwargs)
IMPORT_STATE = (("C", _(u"Created")),
@@ -1257,6 +1268,8 @@ IMPORT_STATE = (("C", _(u"Created")),
("IP", _(u"Import in progress")),
("F", _(u"Finished")))
+IMPORT_STATE_DCT = dict(IMPORT_STATE)
+
class Import(models.Model):
user = models.ForeignKey('IshtarUser')
importer_type = models.ForeignKey(ImporterType)
@@ -1285,15 +1298,40 @@ class Import(models.Model):
return u"%s - %s" % (unicode(self.importer_type),
unicode(self.user))
+ def get_actions(self):
+ """
+ Get available action relevant with the current status
+ """
+ actions = []
+ if self.state == 'C':
+ actions.append(('A', _(u"Analyse")))
+ if self.state == 'A':
+ if ImporterType.objects.filter(pk=self.importer_type.pk,
+ columns__targets__keys__is_set=False).count():
+ actions.append(('L', _(u"Link unmatched items")))
+ actions.append(('A', _(u"Re-analyse")))
+ actions.append(('I', _(u"Launch import")))
+ actions.append(('D', _(u"Delete")))
+ return actions
+
@property
- def importer_instance(self):
- return self.importer_type.importer_class(skip_lines=self.skip_lines,
- import_instance=self)
+ def imported_filename(self):
+ return self.imported_file.name.split(os.sep)[-1]
+
+ @property
+ def status(self):
+ if self.state not in IMPORT_STATE_DCT:
+ return ""
+ return IMPORT_STATE_DCT[self.state]
+
+ def get_importer_instance(self):
+ return self.importer_type.get_importer_class()(
+ skip_lines=self.skip_lines, import_instance=self)
@property
def data_table(self):
encodings = [settings.ENCODING, settings.ALT_ENCODING, 'utf-8']
- with open(self.imported_file.filename) as csv_file:
+ with open(self.imported_file.path) as csv_file:
for encoding in encodings:
try:
return [line for line in unicodecsv.reader(csv_file,
@@ -1305,7 +1343,11 @@ class Import(models.Model):
return []
def initialize(self):
- self.importer_instance.initialize(self.data_table, output='db')
+ self.state = 'AP'
+ self.save()
+ self.get_importer_instance().initialize(self.data_table, output='db')
+ self.state = 'A'
+ self.save()
class Organization(Address, Merge, OwnPerms, ValueGetter):
TABLE_COLS = ('name', 'organization_type',)
diff --git a/ishtar_common/templates/ishtar/form.html b/ishtar_common/templates/ishtar/form.html
new file mode 100644
index 000000000..1e795c540
--- /dev/null
+++ b/ishtar_common/templates/ishtar/form.html
@@ -0,0 +1,13 @@
+{% extends "base.html" %}
+{% load i18n inline_formset %}
+{% block content %}
+<h2>{{page_name}}</h2>
+<div class='form'>
+<form enctype="multipart/form-data" action="." method="post">{% csrf_token %}
+<table>
+{{form}}
+</table>
+<input type="submit" value="{% trans "Validate" %}"/>
+</form>
+</div>
+{% endblock %}
diff --git a/ishtar_common/templates/ishtar/import_list.html b/ishtar_common/templates/ishtar/import_list.html
new file mode 100644
index 000000000..868ca9c9e
--- /dev/null
+++ b/ishtar_common/templates/ishtar/import_list.html
@@ -0,0 +1,47 @@
+{% extends "base.html" %}
+{% load i18n inline_formset %}
+{% block content %}
+<h2>{{page_name}}</h2>
+<div class='form'>
+{% if not object_list %}
+<p>{% trans "No pending imports." %}</p>
+{% else %}
+<form action="." method="post">{% csrf_token %}
+<table>
+<tr>
+ <th>{% trans "Type" %}</th>
+ <th>{% trans "Filename" %}</th>
+ <th>{% trans "Creation" %}</th>
+ <th>{% trans "Status" %}</th>
+</tr>
+{% for import in object_list %}
+<tr>
+ <td>
+ {{import.importer_type}}
+ </td>
+ <td>
+ {{import.imported_filename}}
+ </td>
+ <td>
+ {{import.creation_date}}
+ </td>
+ <td>
+ {{import.status}}
+ </td>
+ <td>
+ <select name='import-action-{{import.pk}}'>
+ <option value=''>--------</option>
+ {% for action, lbl in import.get_actions %}
+ <option value='{{action}}'>{{lbl}}</option>
+ {% endfor%}
+ </select>
+ </td>
+</tr>
+{% endfor %}
+</table>
+ <input type="submit" value="{% trans "Validate" %}"/>
+</form>
+{% endif %}
+</div>
+{% endblock %}
+
diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py
index d1e88f68f..81b96967a 100644
--- a/ishtar_common/urls.py
+++ b/ishtar_common/urls.py
@@ -48,6 +48,11 @@ urlpatterns = patterns('',
views.organization_deletion_wizard, name='organization_deletion'),
url(r'account_management/(?P<step>.+)?$',
views.account_management_wizard, name='account_management'),
+ url(r'import/$', views.NewImportView.as_view(), name='new_import'),
+ url(r'import-list/$', views.ImportListView.as_view(),
+ name='current_imports'),
+ url(r'import-list-old/$', views.ImportOldListView.as_view(),
+ name='old_imports')
)
for section in menu.childs:
for menu_item in section.childs:
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index 6f18f8daa..3c2aa8b3c 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -38,11 +38,14 @@ from django.core import serializers
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse, NoReverseMatch
from django.db.models import Q, F, ImageField
-from django.http import HttpResponse, Http404
+from django.forms.models import model_to_dict, modelformset_factory
+from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext, loader
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext, ugettext_lazy as _
+from django.views.generic import ListView
+from django.views.generic.edit import CreateView
from xhtml2odt import xhtml2odt
@@ -787,10 +790,6 @@ def dashboard_main_detail(request, item_name):
return render_to_response('ishtar/dashboards/dashboard_main_detail.html',
dct, context_instance=RequestContext(request))
-from django.forms.models import model_to_dict
-
-from django.forms.models import modelformset_factory
-
ITEM_PER_PAGE = 20
def merge_action(model, form, key):
def merge(request, page=1):
@@ -832,6 +831,13 @@ person_merge = merge_action(models.Person, forms.MergePersonForm, 'person')
organization_merge = merge_action(models.Organization, forms.MergeOrganizationForm,
'organization')
+class IshtarMixin(object):
+ page_name = u""
+ def get_context_data(self, **kwargs):
+ context = super(IshtarMixin, self).get_context_data(**kwargs)
+ context['page_name'] = self.page_name
+ return context
+
class LoginRequiredMixin(object):
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
@@ -856,3 +862,56 @@ class GlobalVarEdit(AdminLoginRequiredMixin, ModelFormSetView):
extra = 1
can_delete = True
fields = ['slug', 'value', 'description']
+
+class NewImportView(IshtarMixin, LoginRequiredMixin, CreateView):
+ template_name = 'ishtar/form.html'
+ model = models.Import
+ form_class = forms.NewImportForm
+ page_name = _(u"New import")
+
+ def get_success_url(self):
+ return reverse('current_imports')
+
+ def form_valid(self, form):
+ user = models.IshtarUser.objects.get(pk=self.request.user.pk)
+ self.object = form.save(user=user)
+ return HttpResponseRedirect(self.get_success_url())
+
+class ImportListView(IshtarMixin, LoginRequiredMixin, ListView):
+ template_name = 'ishtar/import_list.html'
+ model = models.Import
+ page_name = _(u"Current imports")
+ current_url = 'current_imports'
+
+ def get_queryset(self):
+ user = models.IshtarUser.objects.get(pk=self.request.user.pk)
+ return self.model.objects.filter(user=user).exclude(state='F'
+ ).order_by('-creation_date')
+
+ def post(self, request, *args, **kwargs):
+ for field in request.POST:
+ if not field.startswith('import-action-') or \
+ not request.POST[field]:
+ continue
+ # prevent forged forms
+ try:
+ imprt = models.Import.objects.get(pk=int(field.split('-')[-1]))
+ except (models.Import.DoesNotExist, ValueError):
+ continue
+ # user can only edit his own imports
+ user = models.IshtarUser.objects.get(pk=self.request.user.pk)
+ if imprt.user != user:
+ continue
+ action = request.POST[field]
+ if action == 'D':
+ imprt.delete()
+ elif action == 'A':
+ imprt.initialize()
+ return HttpResponseRedirect(reverse(self.current_url))
+
+class ImportOldListView(ImportListView):
+ current_url = 'old_imports'
+ def get_queryset(self):
+ user = models.IshtarUser.objects.get(pk=self.request.user.pk)
+ return self.model.objects.filter(user=user, state='F'
+ ).order_by('-creation_date')