Skip to main content

A Django library for importing CSVs and other structured data quickly using Django's ModelForm for validation and deserialisation into an instance.

Project description

django-model-import

PyPI version Build Status

Django Model Import is a light weight CSV importer built for speed.

It uses a standard Django ModelForm to parse each row, giving you a familiar API to work with for data validation and model instantiation. In most cases, if you already have a ModelForm for the ContentType you are importing you do not need to create an import specific form.

To present feedback to the end-user running the import you can easily generate a preview of the imported data by toggling the commit parameter.

It also provides some import optimized fields for ForeignKey's, allowing preloading all possible values, or caching each lookup as it occurs, or looking up a model where multiple fields are needed to uniquely identify a resource.

Installation

poetry add django-model-import

Quickstart

import djangomodelimport

class BookImporter(djangomodelimport.ImporterModelForm):
    name = forms.CharField()
    author = CachedChoiceField(queryset=Author.objects.all(), to_field='name')

    class Meta:
        model = Book
        fields = (
            'name',
            'author',
        )

with default_storage.open('books.csv', 'rb') as fh:
    data = fh.read().decode("utf-8")

# Use tablib
parser = djangomodelimport.TablibCSVImportParser(BookImporter)
headers, rows = parser.parse(data)

# Process
importer = djangomodelimport.ModelImporter(BookImporter)
preview = importer.process(headers, rows, commit=False)
errors = preview.get_errors()

if errors:
    print(errors)

importresult = importer.process(headers, rows, commit=True)
for result in importresult.get_results():
    print(result.instance)

Composite key lookups

Often a relationship cannot be referenced via a single unique string. For this we can use a CachedChoiceField with a CompositeLookupWidget. The widget looks for the values under the type and variant columns in the source CSV, and does a unique lookup with the field names specified in to_field, e.g. queryset.get(type__name=type, name=variant).

The results of each get are cached internally for the remainder of the import minimising any database access.

class AssetImporter(ImporterModelForm):
    site = djangomodelimport.CachedChoiceField(queryset=Site.objects.active(), to_field='ref')
    type = djangomodelimport.CachedChoiceField(queryset=AssetType.objects.filter(is_active=True), to_field='name')
    type_variant = djangomodelimport.CachedChoiceField(
        queryset=InspectionItemTypeVariant.objects.filter(is_active=True),
        required=False,
        widget=djangomodelimport.CompositeLookupWidget(source=('type', 'variant')),
        to_field=('type__name', 'name'),
    )
    contractor = djangomodelimport.CachedChoiceField(queryset=Contractor.objects.active(), to_field='name')

Flat related fields

Often you'll have a OneToOneField or just a ForeignKey to another model, but you want to be able to create/update that other model via this one. You can flatten all of the related model's fields onto this importer using FlatRelatedField.

class ClientImporter(ImporterModelForm):
    primary_contact = FlatRelatedField(
        queryset=ContactDetails.objects.all(),
        fields={
            'contact_name': {'to_field': 'name', 'required': True},
            'email': {'to_field': 'email'},
            'email_cc': {'to_field': 'email_cc'},
            'mobile': {'to_field': 'mobile'},
            'phone_bh': {'to_field': 'phone_bh'},
            'phone_ah': {'to_field': 'phone_ah'},
            'fax': {'to_field': 'fax'},
        },
    )

    class Meta:
        model = Client
        fields = (
            'name',
            'ref',
            'is_active',
            'account',

            'primary_contact',
        )

Tests

Run tests with python example/manage.py test testapp

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-model-import-0.4.13.tar.gz (13.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_model_import-0.4.13-py3-none-any.whl (14.4 kB view details)

Uploaded Python 3

File details

Details for the file django-model-import-0.4.13.tar.gz.

File metadata

  • Download URL: django-model-import-0.4.13.tar.gz
  • Upload date:
  • Size: 13.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.6 CPython/3.9.1 Darwin/20.6.0

File hashes

Hashes for django-model-import-0.4.13.tar.gz
Algorithm Hash digest
SHA256 fe32e6287bbbcd6bb61c1946d33a1656f5e0890b2e3c11ba71c5e2c16ca7910a
MD5 ddf2d4d01864b24e69be34a5bc693b2a
BLAKE2b-256 8849f8a044ba5b559899f3b8943d94f804f211bd9f5b34c7a4e9422ee4b36867

See more details on using hashes here.

File details

Details for the file django_model_import-0.4.13-py3-none-any.whl.

File metadata

File hashes

Hashes for django_model_import-0.4.13-py3-none-any.whl
Algorithm Hash digest
SHA256 e1e6cb433c3ca744b7365b66669feb6a809132fb62f5fd02e40ff68138669be9
MD5 2364bc38ec44dce3ed45ad50a95bb091
BLAKE2b-256 fc5f2312dc9d48f1fda7b478afef9ac42b43428be18d5cc5265dd272adcfe5ea

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page