Skip to main content

django-flat-file-exporter

Reusable Django app to request, generate asynchronously, store and download flat-file exports (xlsx, csv, tsv, json, html, parquet). It builds on flat-file-renderers for the file generation and on Django's storage API for keeping the results, so files can live on disk, S3, Google Drive... whatever storage backend you configure.

What you get:

  • ExportedFile / ExportStakeholder models tracking each export: status, timings, failure cause and stack, storage key, who requested it and who else has access.
  • BaseExportForm: declare the filters of an export as a normal Django form. Title, description (Markdown) and filter/column catalog are taken from the docstring and the form fields.
  • BaseExportView: GET renders the form, POST validates it, registers the export and enqueues your task.
  • BaseExportService: renders the dataset with the chosen renderer, uploads to the storage and records every step.
  • A ready-made UI (catalog, list with live status polling, download, trash) and Django admin.

Install

pip install "django-flat-file-exporter[all]"   # [all] = xlsx + parquet renderers and Celery

Requires Python 3.10+ and Django 5.2+. Celery is optional: any object with a delay(exported_file_id, **data) method works as the task.

Setup

# settings.py
INSTALLED_APPS = [
    # ...
    "django.contrib.humanize",
    "flat_file_exporter",
]

# urls.py
urlpatterns = [
    path("exports/", include("flat_file_exporter.urls")),
]
python manage.py migrate

Grant users the flat_file_exporter.view_exportedfile permission to let them use the pages.

Declare an export

# people/forms.py  (forms are discovered in the `forms` module of every installed app)
from django import forms
from flat_file_exporter.forms import BaseExportForm, ExportColumn


class PeopleExportForm(BaseExportForm):
    """People list

    All the people, optionally filtered by age. Markdown is supported here.
    """

    url_name = "people:export"  # URL name of the view below
    columns = [ExportColumn("name", "Full name"), ExportColumn("age")]

    min_age = forms.IntegerField(label="Minimum age", required=False)
# people/tasks.py
from celery import shared_task
from flat_file_exporter.models import ExportedFile
from flat_file_exporter.services import BaseExportService


class PeopleService(BaseExportService):
    def get_dataset(self):  # a list of dicts, a dict, or a QuerySet
        return list(Person.objects.values("name", "age"))


@shared_task
def people_export(exported_file_id, filetype="csv", **filters):
    PeopleService(ExportedFile.objects.get(pk=exported_file_id), filetype).render()
# people/views.py and urls.py
from flat_file_exporter.views import BaseExportView


class PeopleExportView(BaseExportView):
    permission_required = "flat_file_exporter.view_exportedfile"
    form_class = PeopleExportForm
    task_ref = people_export
    content_type_export = "application/zip"


urlpatterns = [path("export/", PeopleExportView.as_view(), name="export")]  # app_name = "people"

The export now appears in the catalog at /exports/. The user picks a format in the form, the task runs in the background, and the list page polls the status until the file can be downloaded.

Settings

Setting Default Meaning
FLAT_FILE_EXPORTER_STORAGE_ALIAS "default" Alias in STORAGES used to save the generated files
FLAT_FILE_EXPORTER_UPLOAD_PREFIX "flat_file_exporter" Directory inside the storage
FLAT_FILE_EXPORTER_FILETYPES see conf.DEFAULT_FILETYPES Filetype to renderer map; entries replace the defaults, None removes one
FLAT_FILE_EXPORTER_BASE_TEMPLATE "flat_file_exporter/base.html" Layout the pages extend
FLAT_FILE_EXPORTER_VISIBILITY "own" "own": users see only exports they are a stakeholder of; "all": every export

The bundled base layout loads Bootstrap 4, jQuery and Font Awesome 5 from CDNs. To use your own layout (for example AdminLTE 3), point FLAT_FILE_EXPORTER_BASE_TEMPLATE at a template that provides the blocks extra_styles, content and bottom_scripts, with jQuery and Bootstrap 4 loaded.

Translations

All texts are translatable (gettext), with English as the source language. A pt_BR catalog is included; the language follows Django's active language (LANGUAGE_CODE / LocaleMiddleware). The strings used by the bundled JavaScript are delivered by the list page as window.flatFileExporterI18n.

To add a language, run django-admin makemessages -l <code> inside the flat_file_exporter directory, translate locale/<code>/LC_MESSAGES/django.po and run django-admin compilemessages. Note that the {% trans %} tag doubles % when looking a message up, so msgids that contain %s in the templates are %%s in the catalog.

Security notes

  • Downloading and trashing an export requires being one of its stakeholders (the requester is added automatically).
  • The failure stack trace is only returned by the status endpoint to superusers.
  • Generated files are read through the storage API; make sure the storage you configure is not publicly readable.

Development

uv venv && uv pip install -e ".[dev]"
pytest --cov
ruff check . && ruff format --check .

License

MIT

Metadata

Release files for django-flat-file-exporter 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-flat-file-exporter 0.1.0
File Size Uploaded Provenance
django_flat_file_exporter-0.1.0.tar.gz 39.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for django-flat-file-exporter 0.1.0
File Interpreter ABI Platform
django_flat_file_exporter-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 79.1 kB

Release files / django_flat_file_exporter-0.1.0.tar.gz

Download URL django_flat_file_exporter-0.1.0.tar.gz
Size 39.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0e0accb6757dccba5bba8603002e5776da95e60a35c26d3ffc4ad828186bae6b
BLAKE2b-256 checksum
How to use checksums
cd7056d7a9ce3741fd685abffecb00e411bf92486c4e86442533d29670adfff2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / django_flat_file_exporter-0.1.0-py3-none-any.whl

Download URL django_flat_file_exporter-0.1.0-py3-none-any.whl
Size 39.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f1758b24b1ff9ccf734d45adff7545872ec33b4fcca316ae5cf9f94ea2f05ad7
BLAKE2b-256 checksum
How to use checksums
6d76cdb009aef0bafbae0c139d60a73e9435147d5509d16c58f2345ae5bc35a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Security for django-flat-file-exporter 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for django_flat_file_exporter-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page