Django application and library for importing and exporting data with included admin integration.
—
Core system for defining how Django models map to import/export data, including field mapping, data transformation, and business logic hooks.
The base Resource class provides the foundation for all import/export operations, with extensive hooks for customization.
class Resource(metaclass=DeclarativeMetaclass):
def __init__(self, **kwargs):
"""
Initialize resource with optional kwargs for dynamic configuration.
Parameters:
- **kwargs: Dynamic values to enhance import/exports
"""
def import_data(self, dataset, dry_run=False, raise_errors=False, use_transactions=None, collect_failed_rows=False, rollback_on_validation_errors=False, **kwargs):
"""
Import data from dataset with comprehensive error handling and transaction support.
Parameters:
- dataset: tablib.Dataset containing import data
- dry_run: bool, perform validation without saving
- raise_errors: bool, raise exceptions on errors
- use_transactions: bool, use database transactions
- collect_failed_rows: bool, collect failed rows for analysis
- rollback_on_validation_errors: bool, rollback on validation errors
- **kwargs: Additional import options
Returns:
Result object containing import results and errors
"""
def export(self, queryset=None, **kwargs):
"""
Export data to dataset format.
Parameters:
- queryset: Django QuerySet to export (defaults to all instances)
- **kwargs: Export configuration options
Returns:
tablib.Dataset containing exported data
"""
def import_row(self, row, instance_loader, **kwargs):
"""
Import a single row of data.
Parameters:
- row: dict, single row data
- instance_loader: Instance loader for retrieving existing instances
- **kwargs: Row processing options
Returns:
RowResult object
"""
def get_or_init_instance(self, instance_loader, row):
"""
Get existing instance or initialize new one for row.
Parameters:
- instance_loader: Instance loader
- row: dict, row data
Returns:
Tuple of (instance, created_flag)
"""
def get_instance(self, instance_loader, row):
"""
Get existing instance for row data.
Parameters:
- instance_loader: Instance loader
- row: dict, row data
Returns:
Model instance or None
"""
def init_instance(self, row=None):
"""
Initialize new instance.
Parameters:
- row: dict, optional row data
Returns:
New model instance
"""
def validate_instance(self, instance, import_validation_errors=None, validate_unique=True):
"""
Validate model instance before saving.
Parameters:
- instance: Model instance to validate
- import_validation_errors: List to collect validation errors
- validate_unique: bool, perform unique validation
"""
def save_instance(self, instance, is_create, row, **kwargs):
"""
Save model instance to database.
Parameters:
- instance: Model instance to save
- is_create: bool, whether this is a new instance
- row: dict, row data
- **kwargs: Save options
"""
def delete_instance(self, instance, row, **kwargs):
"""
Delete model instance from database.
Parameters:
- instance: Model instance to delete
- row: dict, row data
- **kwargs: Delete options
"""
# Bulk operation methods
def bulk_create(self, using_transactions, dry_run, raise_errors, batch_size=None, result=None):
"""
Perform bulk creation of instances for performance optimization.
Parameters:
- using_transactions: bool, use database transactions
- dry_run: bool, perform validation without saving
- raise_errors: bool, raise exceptions on errors
- batch_size: int, number of instances per batch
- result: Result object to update
"""
def bulk_update(self, using_transactions, dry_run, raise_errors, batch_size=None, result=None):
"""
Perform bulk update of instances for performance optimization.
Parameters:
- using_transactions: bool, use database transactions
- dry_run: bool, perform validation without saving
- raise_errors: bool, raise exceptions on errors
- batch_size: int, number of instances per batch
- result: Result object to update
"""
def bulk_delete(self, using_transactions, dry_run, raise_errors, result=None):
"""
Perform bulk deletion of instances for performance optimization.
Parameters:
- using_transactions: bool, use database transactions
- dry_run: bool, perform validation without saving
- raise_errors: bool, raise exceptions on errors
- result: Result object to update
"""
# Lifecycle hook methods for customization
def before_import(self, dataset, **kwargs):
"""
Called before the import process starts.
Parameters:
- dataset: tablib.Dataset to be imported
- **kwargs: Import options
"""
def after_import(self, dataset, result, **kwargs):
"""
Called after the import process completes.
Parameters:
- dataset: tablib.Dataset that was imported
- result: Result object with import results
- **kwargs: Import options
"""
def before_import_row(self, row, **kwargs):
"""
Called before each row is imported.
Parameters:
- row: dict, row data to be imported
- **kwargs: Row import options
"""
def after_import_row(self, row, row_result, **kwargs):
"""
Called after each row is imported.
Parameters:
- row: dict, row data that was imported
- row_result: RowResult object with row import results
- **kwargs: Row import options
"""
def before_save_instance(self, instance, row, **kwargs):
"""
Called before saving an instance.
Parameters:
- instance: Model instance to be saved
- row: dict, row data
- **kwargs: Save options
"""
def after_save_instance(self, instance, row, **kwargs):
"""
Called after saving an instance.
Parameters:
- instance: Model instance that was saved
- row: dict, row data
- **kwargs: Save options
"""
def before_delete_instance(self, instance, row, **kwargs):
"""
Called before deleting an instance.
Parameters:
- instance: Model instance to be deleted
- row: dict, row data
- **kwargs: Delete options
"""
def after_delete_instance(self, instance, row, **kwargs):
"""
Called after deleting an instance.
Parameters:
- instance: Model instance that was deleted
- row: dict, row data
- **kwargs: Delete options
"""
def before_export(self, queryset, **kwargs):
"""
Called before the export process starts.
Parameters:
- queryset: Django QuerySet to be exported
- **kwargs: Export options
"""
def after_export(self, queryset, dataset, **kwargs):
"""
Called after the export process completes.
Parameters:
- queryset: Django QuerySet that was exported
- dataset: tablib.Dataset with exported data
- **kwargs: Export options
"""
def import_field(self, field, instance, row, is_m2m=False, **kwargs):
"""
Import single field value to instance.
Parameters:
- field: Field object
- instance: Model instance
- row: dict, row data
- is_m2m: bool, whether field is many-to-many
- **kwargs: Field import options
"""
def save_m2m(self, instance, row, **kwargs):
"""
Save many-to-many relationships after instance is saved.
Parameters:
- instance: Model instance
- row: dict, row data
- **kwargs: M2M save options
"""
def skip_row(self, instance, original, row, import_validation_errors=None):
"""
Determine whether to skip importing this row.
Parameters:
- instance: Model instance
- original: Original instance (if updating)
- row: dict, row data
- import_validation_errors: List of validation errors
Returns:
bool, True to skip row
"""
def for_delete(self, row, instance):
"""
Determine whether instance should be deleted.
Parameters:
- row: dict, row data
- instance: Model instance
Returns:
bool, True to delete instance
"""
def get_import_fields(self):
"""
Get fields used for import operations.
Returns:
List of Field objects for import
"""
def get_export_fields(self, selected_fields=None):
"""
Get fields used for export operations.
Parameters:
- selected_fields: Optional list of field names to export
Returns:
List of Field objects for export
"""
def get_import_order(self):
"""
Get processing order for import operations.
Returns:
List of field names in import order
"""
def get_export_order(self):
"""
Get field order for export operations.
Returns:
List of field names in export order
"""
def before_import(self, dataset, **kwargs):
"""
Hook called before import process starts.
Parameters:
- dataset: tablib.Dataset to be imported
- **kwargs: Import configuration
"""
def after_import(self, dataset, result, **kwargs):
"""
Hook called after import process completes.
Parameters:
- dataset: tablib.Dataset that was imported
- result: Result object with import results
- **kwargs: Import configuration
"""
def before_import_row(self, row, **kwargs):
"""
Hook called before each row is imported.
Parameters:
- row: dict, row data to be imported
- **kwargs: Row processing options
"""
def after_import_row(self, row, row_result, **kwargs):
"""
Hook called after each row is imported.
Parameters:
- row: dict, row data that was imported
- row_result: RowResult object
- **kwargs: Row processing options
"""
def before_save_instance(self, instance, row, **kwargs):
"""
Hook called before instance is saved.
Parameters:
- instance: Model instance to be saved
- row: dict, row data
- **kwargs: Save options
"""
def after_save_instance(self, instance, row, **kwargs):
"""
Hook called after instance is saved.
Parameters:
- instance: Model instance that was saved
- row: dict, row data
- **kwargs: Save options
"""
def before_delete_instance(self, instance, row, **kwargs):
"""
Hook called before instance is deleted.
Parameters:
- instance: Model instance to be deleted
- row: dict, row data
- **kwargs: Delete options
"""
def after_delete_instance(self, instance, row, **kwargs):
"""
Hook called after instance is deleted.
Parameters:
- instance: Model instance that was deleted
- row: dict, row data
- **kwargs: Delete options
"""
# Bulk operations
def bulk_create(self, using_transactions, dry_run, raise_errors, batch_size=None, result=None):
"""
Bulk create instances for improved performance.
Parameters:
- using_transactions: bool, use database transactions
- dry_run: bool, perform dry run without saving
- raise_errors: bool, raise exceptions on errors
- batch_size: int, batch size for bulk operations
- result: Result object to update
"""
def bulk_update(self, using_transactions, dry_run, raise_errors, batch_size=None, result=None):
"""
Bulk update instances for improved performance.
Parameters:
- using_transactions: bool, use database transactions
- dry_run: bool, perform dry run without saving
- raise_errors: bool, raise exceptions on errors
- batch_size: int, batch size for bulk operations
- result: Result object to update
"""
def bulk_delete(self, using_transactions, dry_run, raise_errors, result=None):
"""
Bulk delete instances for improved performance.
Parameters:
- using_transactions: bool, use database transactions
- dry_run: bool, perform dry run without deleting
- raise_errors: bool, raise exceptions on errors
- result: Result object to update
"""Specialized resource class for Django models with automatic field mapping and Django-specific functionality.
class ModelResource(Resource, metaclass=ModelDeclarativeMetaclass):
def get_queryset(self):
"""
Get Django QuerySet for export operations.
Returns:
QuerySet for the resource's model
"""
def field_from_django_field(self, field_name, django_field, readonly):
"""
Create import_export Field from Django model field.
Parameters:
- field_name: str, name of the field
- django_field: Django model field instance
- readonly: bool, whether field is read-only
Returns:
Field instance configured for Django field
"""
def widget_from_django_field(self, f, default=None):
"""
Create widget from Django model field.
Parameters:
- f: Django model field instance
- default: Default widget class
Returns:
Widget instance appropriate for field type
"""
def widget_kwargs_for_field(self, field_name, django_field):
"""
Get widget kwargs for Django field.
Parameters:
- field_name: str, name of the field
- django_field: Django model field instance
Returns:
Dict of kwargs for widget initialization
"""
def get_display_name(self):
"""
Get display name for the resource.
Returns:
str, human-readable resource name
"""
class Meta:
"""
Meta class for ModelResource configuration.
Attributes:
- model: Django model class
- fields: Tuple of field names to include
- exclude: Tuple of field names to exclude
- import_id_fields: Tuple of fields used for import identification
- export_order: Tuple defining field order in exports
- widgets: Dict mapping field names to widget instances
- use_transactions: bool, use database transactions
- skip_unchanged: bool, skip unchanged records
- use_bulk: bool, use bulk operations for performance
- batch_size: int, batch size for bulk operations
"""Utility function for dynamically creating ModelResource classes.
def modelresource_factory(model, resource_class=ModelResource, meta_options=None, custom_fields=None, dehydrate_methods=None):
"""
Factory function for creating ModelResource classes dynamically.
Parameters:
- model: Django model class
- resource_class: Base resource class (default: ModelResource)
- meta_options: Dict of Meta class options
- custom_fields: Dict of custom field definitions
- dehydrate_methods: Dict of custom dehydrate methods
Returns:
Dynamically created ModelResource class
"""Represents mapping between instance field and its import/export representation.
class Field:
empty_values = [None, ""]
def __init__(self, attribute=None, column_name=None, widget=None, default=NOT_PROVIDED, readonly=False, saves_null_values=True, dehydrate_method=None, m2m_add=False):
"""
Initialize field with mapping configuration.
Parameters:
- attribute: str, instance attribute name
- column_name: str, column name in import/export data
- widget: Widget instance for data transformation
- default: Default value for empty values
- readonly: bool, field is read-only on import
- saves_null_values: bool, save null values to instance
- dehydrate_method: str or callable, custom dehydration method
- m2m_add: bool, add to M2M instead of replacing
"""
def clean(self, row, **kwargs):
"""
Convert import value to Python object.
Parameters:
- row: dict, row data
- **kwargs: Cleaning options
Returns:
Cleaned Python value
"""
def export(self, instance, **kwargs):
"""
Convert instance value to export representation.
Parameters:
- instance: Model instance
- **kwargs: Export options
Returns:
Serialized value for export
"""
def get_value(self, instance):
"""
Get value from instance attribute.
Parameters:
- instance: Model instance
Returns:
Attribute value
"""
def save(self, instance, row, is_m2m=False, **kwargs):
"""
Save cleaned value to instance.
Parameters:
- instance: Model instance
- row: dict, row data
- is_m2m: bool, whether field is many-to-many
- **kwargs: Save options
"""
def get_dehydrate_method(self, field_name=None):
"""
Get method name for dehydration.
Parameters:
- field_name: str, field name
Returns:
str, dehydrate method name
"""Resource behavior can be configured through the Meta class or ResourceOptions.
class ResourceOptions:
"""
Configuration class for Resource behavior.
Common options:
- model: Django model class
- fields: Fields to include in import/export
- exclude: Fields to exclude from import/export
- import_id_fields: Fields used for import identification
- widgets: Custom widgets for specific fields
- use_transactions: Use database transactions
- skip_unchanged: Skip unchanged records during import
- use_bulk: Use bulk operations for performance
- batch_size: Batch size for bulk operations
- chunk_size: Chunk size for processing large datasets
"""def has_natural_foreign_key(model):
"""
Determine if a model has natural foreign key functions.
Parameters:
- model: Django model class
Returns:
bool, True if model supports natural keys
"""from import_export import resources, fields, widgets
from myapp.models import Book
class BookResource(resources.ModelResource):
title = fields.Field(attribute='title', column_name='Book Title')
author = fields.Field(attribute='author', column_name='Author Name')
published_date = fields.Field(
attribute='published_date',
widget=widgets.DateWidget(format='%Y-%m-%d')
)
class Meta:
model = Book
fields = ('id', 'title', 'author', 'published_date')
export_order = ('title', 'author', 'published_date')
import_id_fields = ('id',)class BookResource(resources.ModelResource):
class Meta:
model = Book
def before_import_row(self, row, **kwargs):
# Clean data before processing
row['title'] = row['title'].strip().title()
def after_save_instance(self, instance, row, **kwargs):
# Send notification after saving
send_book_created_notification(instance)
def skip_row(self, instance, original, row, import_validation_errors=None):
# Skip books with empty titles
return not row.get('title', '').strip()class BookResource(resources.ModelResource):
class Meta:
model = Book
use_bulk = True
batch_size = 1000
skip_unchanged = True
use_transactions = Trueclass BookResource(resources.ModelResource):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Add dynamic field based on kwargs
if kwargs.get('include_stats'):
self.fields['stats'] = fields.Field(
attribute='calculate_stats',
readonly=True
)
def calculate_stats(self, instance):
return f"Pages: {instance.pages}, Rating: {instance.rating}"Install with Tessl CLI
npx tessl i tessl/pypi-django-import-export