Initial import
This commit is contained in:
parent
020a17b051
commit
704c9a6a66
|
@ -0,0 +1,3 @@
|
|||
====================
|
||||
django-import-export
|
||||
====================
|
|
@ -0,0 +1,2 @@
|
|||
VERSION = (0, 0, '1dev')
|
||||
__version__ = '.'.join(map(str, VERSION))
|
|
@ -0,0 +1,107 @@
|
|||
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
|
|
@ -0,0 +1,2 @@
|
|||
Django>=1.4
|
||||
tablib
|
|
@ -0,0 +1 @@
|
|||
PYTHONPATH=".:tests:$PYTHONPATH" django-admin.py test core --settings=settings
|
|
@ -0,0 +1,30 @@
|
|||
from setuptools import setup, find_packages
|
||||
import os
|
||||
|
||||
|
||||
VERSION = __import__("send_instance").__version__
|
||||
|
||||
CLASSIFIERS = [
|
||||
'Framework :: Django',
|
||||
'Intended Audience :: Developers',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Operating System :: OS Independent',
|
||||
'Topic :: Software Development',
|
||||
]
|
||||
|
||||
install_requires = [
|
||||
'tablib',
|
||||
'Django>=1.4.2',
|
||||
]
|
||||
|
||||
setup(
|
||||
name="django-import-export",
|
||||
description="django-import-export",
|
||||
long_description=open(os.path.join(os.path.dirname(__file__),
|
||||
'README.rst')).read(),
|
||||
version=VERSION,
|
||||
author="Informatika Mihelac",
|
||||
author_email="bmihelac@mihelac.org",
|
||||
url="https://github.com/bmihelac/django-import-export",
|
||||
packages=find_packages(exclude=["tests"]),
|
||||
)
|
|
@ -0,0 +1,2 @@
|
|||
ID,Book name,Author email
|
||||
1,Some book,test@example.com
|
|
|
@ -0,0 +1,9 @@
|
|||
from django.db import models
|
||||
|
||||
|
||||
class Book(models.Model):
|
||||
name = models.CharField('Book name', max_length=100)
|
||||
author_email = models.EmailField('Author email', max_length=75, blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
|
@ -0,0 +1,32 @@
|
|||
import os.path
|
||||
|
||||
from django.test import TestCase
|
||||
|
||||
from import_export.core import Importer
|
||||
|
||||
from .models import Book
|
||||
|
||||
|
||||
class BookImporter(Importer):
|
||||
|
||||
model = Book
|
||||
|
||||
|
||||
class ImporterTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.filename = os.path.join(os.path.dirname(__file__), 'exports',
|
||||
'books.csv')
|
||||
|
||||
def test_import_create(self):
|
||||
result = BookImporter(open(self.filename), dry_run=False).run()
|
||||
self.assertFalse(result.has_errors())
|
||||
self.assertEqual(Book.objects.count(), 1)
|
||||
|
||||
def test_import_update(self):
|
||||
Book.objects.create(id=1, name="Other book")
|
||||
result = BookImporter(open(self.filename), dry_run=False).run()
|
||||
self.assertFalse(result.has_errors())
|
||||
self.assertEqual(Book.objects.count(), 1)
|
||||
self.assertEqual(Book.objects.all()[0].name, "Some book")
|
||||
self.assertNotEqual(result[0].orig_fields[1], result[0].fields[1])
|
|
@ -0,0 +1,20 @@
|
|||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': 'haystack_tests.db',
|
||||
}
|
||||
}
|
||||
|
||||
INSTALLED_APPS = [
|
||||
'django.contrib.admin',
|
||||
'django.contrib.auth',
|
||||
'django.contrib.contenttypes',
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.sites',
|
||||
|
||||
'import_export',
|
||||
|
||||
'core',
|
||||
]
|
||||
|
||||
SITE_ID = 1
|
Loading…
Reference in New Issue