Metadata-Version: 2.4
Name: django-treebeard-import-export
Version: 0.1.1
Summary: Generates and imports Excel workbooks for Django (and django-treebeard MP_Node) models.
License-Expression: MIT
Project-URL: Repository, https://github.com/LlewopNomis/django-treebeard-import-export
Project-URL: Issues, https://github.com/LlewopNomis/django-treebeard-import-export/issues
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: django
Requires-Dist: django-treebeard
Requires-Dist: django-allauth
Requires-Dist: openpyxl
Provides-Extra: test
Requires-Dist: pytest; extra == "test"
Requires-Dist: pytest-django; extra == "test"
Dynamic: license-file

# django-treebeard-import-export

[![Tests](https://github.com/LlewopNomis/django-treebeard-import-export/actions/workflows/tests.yml/badge.svg)](https://github.com/LlewopNomis/django-treebeard-import-export/actions/workflows/tests.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)

A Django app that generates Excel (`.xlsx`) import templates for another app's models —
including dropdown validation for foreign keys, choices, booleans, and `django-treebeard`
`MP_Node` parent fields — then reads a filled-in workbook back into the database.

It also supports the reverse direction: populating a freshly generated template with the
current contents of the database, so you get an editable export/snapshot in the same
shape the importer expects.

## How it works

- `create_import_template <app_label>` builds one worksheet per model in the target app,
  with a table, column headers, and Excel data-validation dropdowns for FK/choice/boolean
  fields. Foreign keys are resolved by the related model's natural key (or `email` for the
  user model) rather than by primary key.
- `populate_import_workbook <app_label>` fills that template with the app's current
  database rows, so it can be used as an export or as a starting point for edits.
- `import_workbook <app_label>` reads a filled-in workbook back and creates/updates rows,
  resolving foreign keys and choice fields, and handling `MP_Node` `parent` columns by
  natural key rather than tree position.

Files are read from and written to a fixed location so the two commands chain without
file arguments:

```
<target_app>/media/data_exchange/import_templates/<app_label>_import_template.xlsx
<target_app>/media/data_exchange/import_files/<app_label>_import_file.xlsx
```

A model can opt out of templating entirely with `EXCLUDE_FROM_IMPORT_TEMPLATE = True`.

## Requirements

This is a self-contained, pip-installable Django app — every internal import is a
relative import within the `data_exchange` package (no coupling to a specific host
project layout), and dependencies are declared in `pyproject.toml`: `django`,
`django-treebeard`, `django-allauth`, `openpyxl`.

`django-allauth` is required because the optional `--include-users` worksheet records a
new user's email via `allauth.account.models.EmailAddress`.

Any model you want a template for must implement `get_by_natural_key()` on its manager
(standard Django) — this is how the importer/exporter resolve and reconstruct foreign
keys without relying on primary keys.

## Installation

1. Install the package into your Django project's environment. Until this is published
   to PyPI, install it directly from GitHub or as an editable local checkout:

   ```bash
   pip install git+https://github.com/LlewopNomis/django-treebeard-import-export.git@v0.1.0
   # or, for local development:
   pip install -e /path/to/django-treebeard-import-export
   ```

2. Add it to `INSTALLED_APPS`:

   ```python
   INSTALLED_APPS = [
       ...
       "data_exchange",
   ]
   ```

## Usage

Generate a template for an app's models:

```bash
python manage.py create_import_template <app_label>

# Include a "User" worksheet (matched by email) for models with a user FK
python manage.py create_import_template <app_label> --include-users
```

Fill that template with the app's current database contents:

```bash
python manage.py populate_import_workbook <app_label>

# List which models would be populated, without touching the database
python manage.py populate_import_workbook <app_label> --list-models

# Only populate specific models, or populate everything except some
python manage.py populate_import_workbook <app_label> --only-model=Account,Organisation
python manage.py populate_import_workbook <app_label> --skip-model=FinancialData
```

Edit the workbook (in `<app_label>/media/data_exchange/import_files/`), then import it:

```bash
python manage.py import_workbook <app_label>
```

The importer reports successes, failures, and timing per model to stdout.

## Development

The test suite doesn't depend on a host project. `tests/` ships a minimal Django
settings module (`tests/settings.py`) and a throwaway `tests/testapp` with sample models
(plain fields, an FK, a compound-natural-key FK, choices, a boolean, and an `MP_Node`
tree) that exist only to exercise `data_exchange` end to end - neither is included in the
installed package (see `[tool.setuptools.packages.find]` in `pyproject.toml`).

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e ".[test]"
pytest
```

## License

MIT — see [LICENSE](LICENSE).
