---
name: import-export
description: "django-import-export package guide for Python and Django admin import/export workflows"
metadata:
  languages: "python"
  versions: "4.4.0"
  revision: 2
  updated-on: "2026-03-12"
  source: maintainer
  tags: "django,django-import-export,python,admin,import,export,tablib"
---

# django-import-export Python Package Guide

## Golden Rule

Use `django-import-export` for Django model import/export through Django admin or explicit `ModelResource` classes, and use the versioned upstream docs for the package version in your environment.

- Package: `django-import-export`
- Import path: `import_export`
- Version covered here: `4.4.0`
- Versioned docs root: `https://django-import-export.readthedocs.io/en/4.4.0/`
- PyPI package: `https://pypi.org/project/django-import-export/4.4.0/`

## Install

Pin the package version you are targeting:

```bash
pip install django-import-export==4.4.0
```

With `uv`:

```bash
uv add django-import-export==4.4.0
```

With Poetry:

```bash
poetry add django-import-export==4.4.0
```

Version `4.4.0` requires Python `>=3.9`. PyPI classifiers for this release include Django `4.2`, `5.1`, and `5.2`.

Optional format support is installed through extras. Common examples:

```bash
pip install "django-import-export[xlsx]==4.4.0"
pip install "django-import-export[pandas]==4.4.0"
pip install "django-import-export[all]==4.4.0"
```

PyPI lists these extras for `4.4.0`: `all`, `cli`, `ods`, `pandas`, `xls`, `xlsx`, and `yaml`.

## Django Setup

Add the app:

```python
# settings.py
INSTALLED_APPS = [
    # ...
    "import_export",
]
```

The package has no separate auth system. Access is controlled by Django admin auth, model permissions, and any storage backend credentials you configure for temporary import files.

For admin integration, define a resource and attach it to an admin class:

```python
# admin.py
from django.contrib import admin
from import_export import resources
from import_export.admin import ImportExportModelAdmin

from .models import Book

class BookResource(resources.ModelResource):
    class Meta:
        model = Book
        import_id_fields = ("id",)
        fields = ("id", "name", "author", "price")

@admin.register(Book)
class BookAdmin(ImportExportModelAdmin):
    resource_classes = [BookResource]
```

If you only need one direction, upstream also documents `ImportMixin`, `ExportMixin`, and `ExportActionMixin`.

## Core Usage

### Define a Resource

`ModelResource` is the core abstraction. Use it whenever import/export behavior matters; do not rely on autogenerated defaults once matching, validation, or relation mapping become important.

```python
from import_export import resources

from .models import Book

class BookResource(resources.ModelResource):
    class Meta:
        model = Book
        import_id_fields = ("isbn",)
        fields = ("isbn", "name", "published", "price")
        skip_unchanged = True
        report_skipped = True
```

`import_id_fields` controls update matching. If you omit a stable business key, imports often create duplicates instead of updating rows.

### Programmatic Export

```python
resource = BookResource()
dataset = resource.export()

csv_text = dataset.csv
json_text = dataset.json
```

### Programmatic Import

Always dry-run first:

```python
from tablib import Dataset

resource = BookResource()
dataset = Dataset().load(csv_text, format="csv")

preview = resource.import_data(
    dataset,
    dry_run=True,
    raise_errors=True,
)

if not preview.has_errors():
    resource.import_data(dataset, dry_run=False, raise_errors=True)
```

The admin UI follows the same high-level pattern: upload, preview, confirm, then commit.

### Fields and Relations

Use explicit fields and widgets when column names do not match model fields or when you need relation lookups:

```python
from import_export import fields, resources
from import_export.widgets import ForeignKeyWidget

from .models import Author, Book

class BookResource(resources.ModelResource):
    author = fields.Field(
        column_name="author",
        attribute="author",
        widget=ForeignKeyWidget(Author, "name"),
    )

    class Meta:
        model = Book
        import_id_fields = ("isbn",)
        fields = ("isbn", "name", "author", "published")
```

For `4.4.0`, the changelog calls out a new `CachedForeignKeyWidget`. Prefer it when repeated foreign-key lookups dominate import time.

## High-Value Resource Options

These `Meta` options matter most in production code:

- `fields` and `exclude`: explicit control over the dataset schema.
- `import_id_fields`: defines update matching.
- `skip_unchanged` and `report_skipped`: useful for idempotent refresh imports.
- `clean_model_instances = True`: runs model validation; otherwise model `full_clean()` is not part of the default import path.
- `use_bulk = True`: faster inserts/updates, with behavior tradeoffs.
- `batch_size` and `chunk_size`: tune large imports.
- `force_init_instance = True`: only when every row is new and you want to skip instance lookups.
- `use_natural_foreign_keys = True`: useful when serialized data relies on Django natural keys.

When update matching is expensive, upstream also documents using `CachedInstanceLoader` or another `instance_loader_class`.

## Admin Configuration and Permissions

The admin workflow depends on temporary storage between the upload step and the confirmation step. In production, especially with multiple workers or containers, configure shared temporary storage instead of relying on a local temp directory.

Settings and hooks that matter most:

- `IMPORT_EXPORT_TMP_STORAGE_CLASS`: choose filesystem, cache, or Django storage-backed temp storage.
- `IMPORT_EXPORT_SKIP_ADMIN_CONFIRM`: disables the preview/confirm step.
- `IMPORT_EXPORT_SKIP_ADMIN_EXPORT_UI`: skips the export form UI.
- `IMPORT_EXPORT_IMPORT_PERMISSION_CODE` and `IMPORT_EXPORT_EXPORT_PERMISSION_CODE`: customize which permission codename gates admin import/export.
- `IMPORT_EXPORT_ESCAPE_FORMULAE_ON_EXPORT`: escapes spreadsheet formulas for admin exports.

If you use `STORAGES` with Django 4.2+, point the import-export temp storage at a backend available to every app instance.

## Bulk Import Caveats

Bulk mode is useful, but it changes behavior:

- `save()` is not called per instance.
- `pre_save` and `post_save` signals do not fire.
- many-to-many relations are not supported in bulk mode.
- debugging is harder because failures can happen per batch instead of per row.

Use bulk mode only when those tradeoffs are acceptable.

## Common Pitfalls

### Using `latest` docs against a pinned dependency

The docs URL points at `/latest/`, but on March 12, 2026 that root showed `4.4.1.dev33`. For package version `4.4.0`, use `https://django-import-export.readthedocs.io/en/4.4.0/`.

### Duplicate rows during import

This is usually an `import_id_fields` problem. Match on a stable unique field such as `isbn`, slug, or another business key instead of assuming database PKs are present in incoming files.

### Validation is weaker than expected

Resource parsing and widget conversion can succeed even when model-level validation should fail. Turn on `clean_model_instances = True` if you need model validation during import.

### Temporary uploads disappear between requests

This is common in multi-instance deployments when upload and confirm land on different workers. Fix it with shared cache or shared storage for temp files.

### Export sanitization assumptions are wrong

Admin exports can escape spreadsheet formulas with `IMPORT_EXPORT_ESCAPE_FORMULAE_ON_EXPORT`, but the admin docs explicitly say programmatic exports are not sanitized for malicious content. Sanitize untrusted values yourself before handing files to spreadsheet users.

## Version-Sensitive Notes

- This entry is for package version `4.4.0`.
- PyPI lists `4.4.0` as released on January 10, 2026.
- The `4.4.0` changelog entry adds `CachedForeignKeyWidget`, which matters for FK-heavy imports.
- The broader `v4` release line made optional dependencies explicit. If a format handler is missing, install the matching extra instead of assuming it is bundled.
- If you are upgrading from older projects, re-check any custom import/export permissions, temp-storage configuration, and bulk-import assumptions against the `4.4.0` docs.

## Official Sources

- Docs root: https://django-import-export.readthedocs.io/en/4.4.0/
- Admin integration: https://django-import-export.readthedocs.io/en/4.4.0/admin_integration.html
- Resources API: https://django-import-export.readthedocs.io/en/4.4.0/api_resources.html
- Admin API: https://django-import-export.readthedocs.io/en/4.4.0/api_admin.html
- Changelog: https://django-import-export.readthedocs.io/en/4.4.0/changelog.html
- PyPI project page: https://pypi.org/project/django-import-export/4.4.0/
