Initial import

This commit is contained in:
Bojan Mihelac 2012-11-15 16:30:09 +01:00
parent 020a17b051
commit 704c9a6a66
13 changed files with 208 additions and 0 deletions

3
README.rst Normal file
View File

@ -0,0 +1,3 @@
====================
django-import-export
====================

View File

@ -0,0 +1,2 @@
VERSION = (0, 0, '1dev')
__version__ = '.'.join(map(str, VERSION))

107
import_export/core.py Normal file
View File

@ -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
import_export/models.py Normal file
View File

2
requirements.txt Normal file
View File

@ -0,0 +1,2 @@
Django>=1.4
tablib

1
runtests.sh Executable file
View File

@ -0,0 +1 @@
PYTHONPATH=".:tests:$PYTHONPATH" django-admin.py test core --settings=settings

30
setup.py Normal file
View File

@ -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
tests/__init__.py Normal file
View File

0
tests/core/__init__.py Normal file
View File

View File

@ -0,0 +1,2 @@
ID,Book name,Author email
1,Some book,test@example.com
1 ID Book name Author email
2 1 Some book test@example.com

9
tests/core/models.py Normal file
View File

@ -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

32
tests/core/tests.py Normal file
View File

@ -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])

20
tests/settings.py Normal file
View File

@ -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