debian-django-import-export/import_export/core.py

108 lines
3.0 KiB
Python

from collections import OrderedDict
import tablib
from django.utils.translation import ugettext_lazy as _
class RowResult(object):
def __init__(self):
self.errors = []
self.orig_fields = []
self.fields = []
class Result(list):
def __init__(self, *args, **kwargs):
super(Result, self).__init__(*args, **kwargs)
self.base_errors = []
def row_errors(self):
return [(i, row.errors) for i, row in enumerate(self) if row.errors]
def has_errors(self):
return self.base_errors or self.row_errors()
class Importer(object):
model = None
format = None
import_code = "ID"
raise_errors = True
dry_run = True
mapping = None
def __init__(self, f, **kwargs):
self.f = f
for key, value in kwargs.iteritems():
setattr(self, key, value)
def get_mapping(self):
if self.mapping:
return self.mapping
mapping = [(f.verbose_name, f.name) for f in self.model._meta.fields]
return OrderedDict(mapping)
def load_dataset(self):
text = unicode(self.f.read(), 'cp1250').encode('utf-8')
if not self.format:
self.data = tablib.import_set(text)
else:
self.data = tablib.Dataset()
self.format.import_set(self.data, text)
def get_instance(self, row):
return self.model.objects.get(**{
self.get_mapping()[self.import_code]: row[self.import_code]
})
def init_instance(self, row):
return self.model()
def get_or_init_instance(self, row):
try:
instance = self.get_instance(row)
except self.model.DoesNotExist:
instance = self.init_instance(row)
return instance
def set_instance_attr(self, instance, row, field):
setattr(instance, self.get_mapping()[field], row[field])
def save_instance(self, instance):
if not self.dry_run:
instance.save()
def get_representation(self, instance):
return [unicode(getattr(instance, f))
for f in self.get_mapping().values()]
def run(self):
result = Result()
try:
self.load_dataset()
except Exception, e:
result.base_errors.append(_('Loading error') +
u': %s' % unicode(e))
if self.raise_errors:
raise
return result
for row in self.data.dict:
try:
row_result = RowResult()
instance = self.get_or_init_instance(row)
row_result.orig_fields = self.get_representation(instance)
for field in self.get_mapping().keys():
self.set_instance_attr(instance, row, field)
self.save_instance(instance)
row_result.fields = self.get_representation(instance)
except Exception, e:
row_result.errors.append(unicode(e))
if self.raise_errors:
raise
result.append(row_result)
return result