summaryrefslogtreecommitdiff
path: root/ishtar_common/data_importer.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/data_importer.py')
-rw-r--r--ishtar_common/data_importer.py98
1 files changed, 88 insertions, 10 deletions
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py
index 49705f0df..a03f4de34 100644
--- a/ishtar_common/data_importer.py
+++ b/ishtar_common/data_importer.py
@@ -29,6 +29,7 @@ import zipfile
from django.conf import settings
from django.contrib.auth.models import User
+from django.core.exceptions import ImproperlyConfigured
from django.core.files import File
from django.db import IntegrityError, DatabaseError, transaction
from django.template.defaultfilters import slugify
@@ -613,6 +614,8 @@ class Importer(object):
OBJECT_CLS = None
IMPORTED_LINE_FIELD = None
UNICITY_KEYS = []
+ # if set only models inside this list can be created
+ MODEL_CREATION_LIMIT = []
EXTRA_DEFAULTS = {}
DEFAULTS = {}
ERRORS = {
@@ -626,10 +629,19 @@ class Importer(object):
'no_data': _(u"No data provided"),
'value_required': _(u"Value is required"),
'not_enough_cols': _(u"At least %d columns must be filled"),
- 'regex_not_match': _(u"The regexp doesn't match.")
+ 'regex_not_match': _(u"The regexp doesn't match."),
+ 'improperly_configured': _(
+ u"Forced creation is set for model {} but this model is not in the "
+ u"list of models allowed to be created."),
+ 'does_not_exist_in_db': _(u"{} with values {} doesn't exist in the "
+ u"database. Create it first or fix your source file."),
}
def _create_models(self, force=False):
+ """
+ Create a db config from a hardcoded import.
+ Not useful anymore?
+ """
from ishtar_common import models
q = models.ImporterType.objects.filter(slug=self.SLUG)
if not force and (not self.SLUG or q.count()):
@@ -640,6 +652,9 @@ class Importer(object):
model_name = self.OBJECT_CLS.__module__ + '.' + \
self.OBJECT_CLS.__name__
+ model_cls, c = models.ImporterModel.object.get_or_create(
+ klass=model_name, default={'name': self.OBJECT_CLS.__name__}
+ )
unicity_keys = ''
if self.UNICITY_KEYS:
@@ -647,7 +662,7 @@ class Importer(object):
importer = models.ImporterType.objects.create(
slug=self.SLUG, name=name, description=self.DESC,
- associated_models=model_name, unicity_keys=unicity_keys)
+ associated_models=model_cls, unicity_keys=unicity_keys)
for default in self.DEFAULTS:
values = self.DEFAULTS[default]
@@ -712,6 +727,28 @@ class Importer(object):
comment=line.comment)
return True
+ def _get_improperly_conf_error(self, model):
+ from ishtar_common.models import ImporterModel
+ cls_name = model.__module__ + "." + model.__name__
+ q = ImporterModel.objects.filter(klass=cls_name)
+ if q.count():
+ cls_name = q.all()[0].name
+ return ImproperlyConfigured(
+ unicode(self.ERRORS['improperly_configured']).format(cls_name))
+
+ def _get_does_not_exist_in_db_error(self, model, data):
+ from ishtar_common.models import ImporterModel
+ cls_name = model.__module__ + "." + model.__name__
+ q = ImporterModel.objects.filter(klass=cls_name)
+ if q.count():
+ cls_name = q.all()[0].name
+ values = u", ".join(
+ [u"{}: {}".format(k, data[k]) for k in data]
+ )
+ raise ImporterError(
+ unicode(self.ERRORS['does_not_exist_in_db']
+ ).format(cls_name, values))
+
def __init__(self, skip_lines=0, reference_header=None,
check_col_num=False, test=False, history_modifier=None,
output='silent', import_instance=None,
@@ -1006,11 +1043,26 @@ class Importer(object):
if k not in formater.through_unicity_keys \
and k != 'defaults':
data['defaults'][k] = data.pop(k)
+ created = False
if '__force_new' in data:
+ if self.MODEL_CREATION_LIMIT and \
+ through_cls not in self.MODEL_CREATION_LIMIT:
+ raise self._get_improperly_conf_error(through_cls)
created = data.pop('__force_new')
t_obj = through_cls.objects.create(**data)
else:
- t_obj, created = through_cls.objects.get_or_create(**data)
+ if not self.MODEL_CREATION_LIMIT or \
+ through_cls in self.MODEL_CREATION_LIMIT:
+ t_obj, created = through_cls.objects.get_or_create(**data)
+ else:
+ get_data = data.copy()
+ if 'defaults' in get_data:
+ get_data.pop('defaults')
+ try:
+ t_obj = through_cls.objects.get(**get_data)
+ except through_cls.DoesNotExist:
+ raise self._get_does_not_exist_in_db_error(
+ through_cls, get_data)
if not created and 'defaults' in data:
for k in data['defaults']:
setattr(t_obj, k, data['defaults'][k])
@@ -1244,6 +1296,9 @@ class Importer(object):
new_created[attribute].append(key)
has_values = bool([1 for k in v if v[k]])
if has_values:
+ if self.MODEL_CREATION_LIMIT and \
+ model not in self.MODEL_CREATION_LIMIT:
+ raise self._get_improperly_conf_error(model)
v = model.objects.create(**v)
else:
continue
@@ -1252,14 +1307,25 @@ class Importer(object):
extra_fields = {}
# "File" type is a temp object and can be different
# for the same filename - it must be treated
- # separatly
+ # separately
for field in model._meta.fields:
k = field.name
- # attr_class est un attribut de FileField
+ # attr_class is a FileField attribute
if hasattr(field, 'attr_class') and k in v:
extra_fields[k] = v.pop(k)
- v, created = model.objects.get_or_create(
- **v)
+ if not self.MODEL_CREATION_LIMIT or \
+ model in self.MODEL_CREATION_LIMIT:
+ v, created = model.objects.get_or_create(
+ **v)
+ else:
+ get_v = v.copy()
+ if 'defaults' in get_v:
+ get_v.pop('defaults')
+ try:
+ v = model.objects.get(**get_v)
+ except model.DoesNotExist:
+ raise self._get_does_not_exist_in_db_error(
+ model, get_v)
changed = False
for k in extra_fields.keys():
if extra_fields[k]:
@@ -1333,6 +1399,7 @@ class Importer(object):
'history_modifier': create_dict.pop('history_modifier')
})
+ created = False
try:
try:
dct = create_dict.copy()
@@ -1345,6 +1412,9 @@ class Importer(object):
return None, created
new_dct = defaults.copy()
new_dct.update(dct)
+ if self.MODEL_CREATION_LIMIT and \
+ cls not in self.MODEL_CREATION_LIMIT:
+ raise self._get_improperly_conf_error(cls)
obj = cls.objects.create(**new_dct)
else:
# manage UNICITY_KEYS - only level 1
@@ -1353,9 +1423,17 @@ class Importer(object):
if k not in self.UNICITY_KEYS \
and k != 'defaults':
defaults[k] = dct.pop(k)
-
- dct['defaults'] = defaults.copy()
- obj, created = cls.objects.get_or_create(**dct)
+ if not self.MODEL_CREATION_LIMIT or \
+ cls in self.MODEL_CREATION_LIMIT:
+ dct['defaults'] = defaults.copy()
+ obj, created = cls.objects.get_or_create(**dct)
+ else:
+ try:
+ obj = cls.objects.get(**dct)
+ dct['defaults'] = defaults.copy()
+ except cls.DoesNotExist:
+ raise self._get_does_not_exist_in_db_error(
+ cls, dct)
if not created and not path and self.UNICITY_KEYS:
changed = False