or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

admin-integration.mdfile-formats.mdforms-ui.mdindex.mdmanagement-commands.mdresources-fields.mdwidgets-transformation.md

resources-fields.mddocs/

0

# Resources and Fields

1

2

Core system for defining how Django models map to import/export data, including field mapping, data transformation, and business logic hooks.

3

4

## Capabilities

5

6

### Resource Base Class

7

8

The base Resource class provides the foundation for all import/export operations, with extensive hooks for customization.

9

10

```python { .api }

11

class Resource(metaclass=DeclarativeMetaclass):

12

def __init__(self, **kwargs):

13

"""

14

Initialize resource with optional kwargs for dynamic configuration.

15

16

Parameters:

17

- **kwargs: Dynamic values to enhance import/exports

18

"""

19

20

def import_data(self, dataset, dry_run=False, raise_errors=False, use_transactions=None, collect_failed_rows=False, rollback_on_validation_errors=False, **kwargs):

21

"""

22

Import data from dataset with comprehensive error handling and transaction support.

23

24

Parameters:

25

- dataset: tablib.Dataset containing import data

26

- dry_run: bool, perform validation without saving

27

- raise_errors: bool, raise exceptions on errors

28

- use_transactions: bool, use database transactions

29

- collect_failed_rows: bool, collect failed rows for analysis

30

- rollback_on_validation_errors: bool, rollback on validation errors

31

- **kwargs: Additional import options

32

33

Returns:

34

Result object containing import results and errors

35

"""

36

37

def export(self, queryset=None, **kwargs):

38

"""

39

Export data to dataset format.

40

41

Parameters:

42

- queryset: Django QuerySet to export (defaults to all instances)

43

- **kwargs: Export configuration options

44

45

Returns:

46

tablib.Dataset containing exported data

47

"""

48

49

def import_row(self, row, instance_loader, **kwargs):

50

"""

51

Import a single row of data.

52

53

Parameters:

54

- row: dict, single row data

55

- instance_loader: Instance loader for retrieving existing instances

56

- **kwargs: Row processing options

57

58

Returns:

59

RowResult object

60

"""

61

62

def get_or_init_instance(self, instance_loader, row):

63

"""

64

Get existing instance or initialize new one for row.

65

66

Parameters:

67

- instance_loader: Instance loader

68

- row: dict, row data

69

70

Returns:

71

Tuple of (instance, created_flag)

72

"""

73

74

def get_instance(self, instance_loader, row):

75

"""

76

Get existing instance for row data.

77

78

Parameters:

79

- instance_loader: Instance loader

80

- row: dict, row data

81

82

Returns:

83

Model instance or None

84

"""

85

86

def init_instance(self, row=None):

87

"""

88

Initialize new instance.

89

90

Parameters:

91

- row: dict, optional row data

92

93

Returns:

94

New model instance

95

"""

96

97

def validate_instance(self, instance, import_validation_errors=None, validate_unique=True):

98

"""

99

Validate model instance before saving.

100

101

Parameters:

102

- instance: Model instance to validate

103

- import_validation_errors: List to collect validation errors

104

- validate_unique: bool, perform unique validation

105

"""

106

107

def save_instance(self, instance, is_create, row, **kwargs):

108

"""

109

Save model instance to database.

110

111

Parameters:

112

- instance: Model instance to save

113

- is_create: bool, whether this is a new instance

114

- row: dict, row data

115

- **kwargs: Save options

116

"""

117

118

def delete_instance(self, instance, row, **kwargs):

119

"""

120

Delete model instance from database.

121

122

Parameters:

123

- instance: Model instance to delete

124

- row: dict, row data

125

- **kwargs: Delete options

126

"""

127

128

# Bulk operation methods

129

def bulk_create(self, using_transactions, dry_run, raise_errors, batch_size=None, result=None):

130

"""

131

Perform bulk creation of instances for performance optimization.

132

133

Parameters:

134

- using_transactions: bool, use database transactions

135

- dry_run: bool, perform validation without saving

136

- raise_errors: bool, raise exceptions on errors

137

- batch_size: int, number of instances per batch

138

- result: Result object to update

139

"""

140

141

def bulk_update(self, using_transactions, dry_run, raise_errors, batch_size=None, result=None):

142

"""

143

Perform bulk update of instances for performance optimization.

144

145

Parameters:

146

- using_transactions: bool, use database transactions

147

- dry_run: bool, perform validation without saving

148

- raise_errors: bool, raise exceptions on errors

149

- batch_size: int, number of instances per batch

150

- result: Result object to update

151

"""

152

153

def bulk_delete(self, using_transactions, dry_run, raise_errors, result=None):

154

"""

155

Perform bulk deletion of instances for performance optimization.

156

157

Parameters:

158

- using_transactions: bool, use database transactions

159

- dry_run: bool, perform validation without saving

160

- raise_errors: bool, raise exceptions on errors

161

- result: Result object to update

162

"""

163

164

# Lifecycle hook methods for customization

165

def before_import(self, dataset, **kwargs):

166

"""

167

Called before the import process starts.

168

169

Parameters:

170

- dataset: tablib.Dataset to be imported

171

- **kwargs: Import options

172

"""

173

174

def after_import(self, dataset, result, **kwargs):

175

"""

176

Called after the import process completes.

177

178

Parameters:

179

- dataset: tablib.Dataset that was imported

180

- result: Result object with import results

181

- **kwargs: Import options

182

"""

183

184

def before_import_row(self, row, **kwargs):

185

"""

186

Called before each row is imported.

187

188

Parameters:

189

- row: dict, row data to be imported

190

- **kwargs: Row import options

191

"""

192

193

def after_import_row(self, row, row_result, **kwargs):

194

"""

195

Called after each row is imported.

196

197

Parameters:

198

- row: dict, row data that was imported

199

- row_result: RowResult object with row import results

200

- **kwargs: Row import options

201

"""

202

203

def before_save_instance(self, instance, row, **kwargs):

204

"""

205

Called before saving an instance.

206

207

Parameters:

208

- instance: Model instance to be saved

209

- row: dict, row data

210

- **kwargs: Save options

211

"""

212

213

def after_save_instance(self, instance, row, **kwargs):

214

"""

215

Called after saving an instance.

216

217

Parameters:

218

- instance: Model instance that was saved

219

- row: dict, row data

220

- **kwargs: Save options

221

"""

222

223

def before_delete_instance(self, instance, row, **kwargs):

224

"""

225

Called before deleting an instance.

226

227

Parameters:

228

- instance: Model instance to be deleted

229

- row: dict, row data

230

- **kwargs: Delete options

231

"""

232

233

def after_delete_instance(self, instance, row, **kwargs):

234

"""

235

Called after deleting an instance.

236

237

Parameters:

238

- instance: Model instance that was deleted

239

- row: dict, row data

240

- **kwargs: Delete options

241

"""

242

243

def before_export(self, queryset, **kwargs):

244

"""

245

Called before the export process starts.

246

247

Parameters:

248

- queryset: Django QuerySet to be exported

249

- **kwargs: Export options

250

"""

251

252

def after_export(self, queryset, dataset, **kwargs):

253

"""

254

Called after the export process completes.

255

256

Parameters:

257

- queryset: Django QuerySet that was exported

258

- dataset: tablib.Dataset with exported data

259

- **kwargs: Export options

260

"""

261

262

def import_field(self, field, instance, row, is_m2m=False, **kwargs):

263

"""

264

Import single field value to instance.

265

266

Parameters:

267

- field: Field object

268

- instance: Model instance

269

- row: dict, row data

270

- is_m2m: bool, whether field is many-to-many

271

- **kwargs: Field import options

272

"""

273

274

def save_m2m(self, instance, row, **kwargs):

275

"""

276

Save many-to-many relationships after instance is saved.

277

278

Parameters:

279

- instance: Model instance

280

- row: dict, row data

281

- **kwargs: M2M save options

282

"""

283

284

def skip_row(self, instance, original, row, import_validation_errors=None):

285

"""

286

Determine whether to skip importing this row.

287

288

Parameters:

289

- instance: Model instance

290

- original: Original instance (if updating)

291

- row: dict, row data

292

- import_validation_errors: List of validation errors

293

294

Returns:

295

bool, True to skip row

296

"""

297

298

def for_delete(self, row, instance):

299

"""

300

Determine whether instance should be deleted.

301

302

Parameters:

303

- row: dict, row data

304

- instance: Model instance

305

306

Returns:

307

bool, True to delete instance

308

"""

309

310

def get_import_fields(self):

311

"""

312

Get fields used for import operations.

313

314

Returns:

315

List of Field objects for import

316

"""

317

318

def get_export_fields(self, selected_fields=None):

319

"""

320

Get fields used for export operations.

321

322

Parameters:

323

- selected_fields: Optional list of field names to export

324

325

Returns:

326

List of Field objects for export

327

"""

328

329

def get_import_order(self):

330

"""

331

Get processing order for import operations.

332

333

Returns:

334

List of field names in import order

335

"""

336

337

def get_export_order(self):

338

"""

339

Get field order for export operations.

340

341

Returns:

342

List of field names in export order

343

"""

344

345

def before_import(self, dataset, **kwargs):

346

"""

347

Hook called before import process starts.

348

349

Parameters:

350

- dataset: tablib.Dataset to be imported

351

- **kwargs: Import configuration

352

"""

353

354

def after_import(self, dataset, result, **kwargs):

355

"""

356

Hook called after import process completes.

357

358

Parameters:

359

- dataset: tablib.Dataset that was imported

360

- result: Result object with import results

361

- **kwargs: Import configuration

362

"""

363

364

def before_import_row(self, row, **kwargs):

365

"""

366

Hook called before each row is imported.

367

368

Parameters:

369

- row: dict, row data to be imported

370

- **kwargs: Row processing options

371

"""

372

373

def after_import_row(self, row, row_result, **kwargs):

374

"""

375

Hook called after each row is imported.

376

377

Parameters:

378

- row: dict, row data that was imported

379

- row_result: RowResult object

380

- **kwargs: Row processing options

381

"""

382

383

def before_save_instance(self, instance, row, **kwargs):

384

"""

385

Hook called before instance is saved.

386

387

Parameters:

388

- instance: Model instance to be saved

389

- row: dict, row data

390

- **kwargs: Save options

391

"""

392

393

def after_save_instance(self, instance, row, **kwargs):

394

"""

395

Hook called after instance is saved.

396

397

Parameters:

398

- instance: Model instance that was saved

399

- row: dict, row data

400

- **kwargs: Save options

401

"""

402

403

def before_delete_instance(self, instance, row, **kwargs):

404

"""

405

Hook called before instance is deleted.

406

407

Parameters:

408

- instance: Model instance to be deleted

409

- row: dict, row data

410

- **kwargs: Delete options

411

"""

412

413

def after_delete_instance(self, instance, row, **kwargs):

414

"""

415

Hook called after instance is deleted.

416

417

Parameters:

418

- instance: Model instance that was deleted

419

- row: dict, row data

420

- **kwargs: Delete options

421

"""

422

423

# Bulk operations

424

def bulk_create(self, using_transactions, dry_run, raise_errors, batch_size=None, result=None):

425

"""

426

Bulk create instances for improved performance.

427

428

Parameters:

429

- using_transactions: bool, use database transactions

430

- dry_run: bool, perform dry run without saving

431

- raise_errors: bool, raise exceptions on errors

432

- batch_size: int, batch size for bulk operations

433

- result: Result object to update

434

"""

435

436

def bulk_update(self, using_transactions, dry_run, raise_errors, batch_size=None, result=None):

437

"""

438

Bulk update instances for improved performance.

439

440

Parameters:

441

- using_transactions: bool, use database transactions

442

- dry_run: bool, perform dry run without saving

443

- raise_errors: bool, raise exceptions on errors

444

- batch_size: int, batch size for bulk operations

445

- result: Result object to update

446

"""

447

448

def bulk_delete(self, using_transactions, dry_run, raise_errors, result=None):

449

"""

450

Bulk delete instances for improved performance.

451

452

Parameters:

453

- using_transactions: bool, use database transactions

454

- dry_run: bool, perform dry run without deleting

455

- raise_errors: bool, raise exceptions on errors

456

- result: Result object to update

457

"""

458

```

459

460

### ModelResource Class

461

462

Specialized resource class for Django models with automatic field mapping and Django-specific functionality.

463

464

```python { .api }

465

class ModelResource(Resource, metaclass=ModelDeclarativeMetaclass):

466

def get_queryset(self):

467

"""

468

Get Django QuerySet for export operations.

469

470

Returns:

471

QuerySet for the resource's model

472

"""

473

474

def field_from_django_field(self, field_name, django_field, readonly):

475

"""

476

Create import_export Field from Django model field.

477

478

Parameters:

479

- field_name: str, name of the field

480

- django_field: Django model field instance

481

- readonly: bool, whether field is read-only

482

483

Returns:

484

Field instance configured for Django field

485

"""

486

487

def widget_from_django_field(self, f, default=None):

488

"""

489

Create widget from Django model field.

490

491

Parameters:

492

- f: Django model field instance

493

- default: Default widget class

494

495

Returns:

496

Widget instance appropriate for field type

497

"""

498

499

def widget_kwargs_for_field(self, field_name, django_field):

500

"""

501

Get widget kwargs for Django field.

502

503

Parameters:

504

- field_name: str, name of the field

505

- django_field: Django model field instance

506

507

Returns:

508

Dict of kwargs for widget initialization

509

"""

510

511

def get_display_name(self):

512

"""

513

Get display name for the resource.

514

515

Returns:

516

str, human-readable resource name

517

"""

518

519

class Meta:

520

"""

521

Meta class for ModelResource configuration.

522

523

Attributes:

524

- model: Django model class

525

- fields: Tuple of field names to include

526

- exclude: Tuple of field names to exclude

527

- import_id_fields: Tuple of fields used for import identification

528

- export_order: Tuple defining field order in exports

529

- widgets: Dict mapping field names to widget instances

530

- use_transactions: bool, use database transactions

531

- skip_unchanged: bool, skip unchanged records

532

- use_bulk: bool, use bulk operations for performance

533

- batch_size: int, batch size for bulk operations

534

"""

535

```

536

537

### ModelResource Factory

538

539

Utility function for dynamically creating ModelResource classes.

540

541

```python { .api }

542

def modelresource_factory(model, resource_class=ModelResource, meta_options=None, custom_fields=None, dehydrate_methods=None):

543

"""

544

Factory function for creating ModelResource classes dynamically.

545

546

Parameters:

547

- model: Django model class

548

- resource_class: Base resource class (default: ModelResource)

549

- meta_options: Dict of Meta class options

550

- custom_fields: Dict of custom field definitions

551

- dehydrate_methods: Dict of custom dehydrate methods

552

553

Returns:

554

Dynamically created ModelResource class

555

"""

556

```

557

558

### Field Class

559

560

Represents mapping between instance field and its import/export representation.

561

562

```python { .api }

563

class Field:

564

empty_values = [None, ""]

565

566

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):

567

"""

568

Initialize field with mapping configuration.

569

570

Parameters:

571

- attribute: str, instance attribute name

572

- column_name: str, column name in import/export data

573

- widget: Widget instance for data transformation

574

- default: Default value for empty values

575

- readonly: bool, field is read-only on import

576

- saves_null_values: bool, save null values to instance

577

- dehydrate_method: str or callable, custom dehydration method

578

- m2m_add: bool, add to M2M instead of replacing

579

"""

580

581

def clean(self, row, **kwargs):

582

"""

583

Convert import value to Python object.

584

585

Parameters:

586

- row: dict, row data

587

- **kwargs: Cleaning options

588

589

Returns:

590

Cleaned Python value

591

"""

592

593

def export(self, instance, **kwargs):

594

"""

595

Convert instance value to export representation.

596

597

Parameters:

598

- instance: Model instance

599

- **kwargs: Export options

600

601

Returns:

602

Serialized value for export

603

"""

604

605

def get_value(self, instance):

606

"""

607

Get value from instance attribute.

608

609

Parameters:

610

- instance: Model instance

611

612

Returns:

613

Attribute value

614

"""

615

616

def save(self, instance, row, is_m2m=False, **kwargs):

617

"""

618

Save cleaned value to instance.

619

620

Parameters:

621

- instance: Model instance

622

- row: dict, row data

623

- is_m2m: bool, whether field is many-to-many

624

- **kwargs: Save options

625

"""

626

627

def get_dehydrate_method(self, field_name=None):

628

"""

629

Get method name for dehydration.

630

631

Parameters:

632

- field_name: str, field name

633

634

Returns:

635

str, dehydrate method name

636

"""

637

```

638

639

### Resource Configuration

640

641

Resource behavior can be configured through the Meta class or ResourceOptions.

642

643

```python { .api }

644

class ResourceOptions:

645

"""

646

Configuration class for Resource behavior.

647

648

Common options:

649

- model: Django model class

650

- fields: Fields to include in import/export

651

- exclude: Fields to exclude from import/export

652

- import_id_fields: Fields used for import identification

653

- widgets: Custom widgets for specific fields

654

- use_transactions: Use database transactions

655

- skip_unchanged: Skip unchanged records during import

656

- use_bulk: Use bulk operations for performance

657

- batch_size: Batch size for bulk operations

658

- chunk_size: Chunk size for processing large datasets

659

"""

660

```

661

662

### Utility Functions

663

664

```python { .api }

665

def has_natural_foreign_key(model):

666

"""

667

Determine if a model has natural foreign key functions.

668

669

Parameters:

670

- model: Django model class

671

672

Returns:

673

bool, True if model supports natural keys

674

"""

675

```

676

677

## Usage Examples

678

679

### Basic Resource Definition

680

681

```python

682

from import_export import resources, fields, widgets

683

from myapp.models import Book

684

685

class BookResource(resources.ModelResource):

686

title = fields.Field(attribute='title', column_name='Book Title')

687

author = fields.Field(attribute='author', column_name='Author Name')

688

published_date = fields.Field(

689

attribute='published_date',

690

widget=widgets.DateWidget(format='%Y-%m-%d')

691

)

692

693

class Meta:

694

model = Book

695

fields = ('id', 'title', 'author', 'published_date')

696

export_order = ('title', 'author', 'published_date')

697

import_id_fields = ('id',)

698

```

699

700

### Custom Processing with Hooks

701

702

```python

703

class BookResource(resources.ModelResource):

704

class Meta:

705

model = Book

706

707

def before_import_row(self, row, **kwargs):

708

# Clean data before processing

709

row['title'] = row['title'].strip().title()

710

711

def after_save_instance(self, instance, row, **kwargs):

712

# Send notification after saving

713

send_book_created_notification(instance)

714

715

def skip_row(self, instance, original, row, import_validation_errors=None):

716

# Skip books with empty titles

717

return not row.get('title', '').strip()

718

```

719

720

### Bulk Operations Configuration

721

722

```python

723

class BookResource(resources.ModelResource):

724

class Meta:

725

model = Book

726

use_bulk = True

727

batch_size = 1000

728

skip_unchanged = True

729

use_transactions = True

730

```

731

732

### Dynamic Field Configuration

733

734

```python

735

class BookResource(resources.ModelResource):

736

def __init__(self, **kwargs):

737

super().__init__(**kwargs)

738

# Add dynamic field based on kwargs

739

if kwargs.get('include_stats'):

740

self.fields['stats'] = fields.Field(

741

attribute='calculate_stats',

742

readonly=True

743

)

744

745

def calculate_stats(self, instance):

746

return f"Pages: {instance.pages}, Rating: {instance.rating}"

747

```