File: getting_started.rst

package info (click to toggle)
python-django-import-export 4.3.5-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,300 kB
  • sloc: python: 11,650; makefile: 180; sh: 63; javascript: 50
file content (153 lines) | stat: -rw-r--r-- 4,915 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
===============
Getting started
===============

Introduction
============

This section describes how to get started with import-export.  We'll use the :ref:`example application<exampleapp>`
as a guide.

import-export can be used programmatically as described here, or it can be integrated with the
:ref:`Django Admin interface<admin-integration>`.

Test data
=========

There are sample files which can be used to test importing data in the `tests/core/exports` directory.

The test models
===============

For example purposes, we'll use a simplified book app. Here is our
``models.py``::

    # app/models.py

    class Author(models.Model):
        name = models.CharField(max_length=100)

        def __str__(self):
            return self.name


    class Category(models.Model):
        name = models.CharField(max_length=100)

        def __str__(self):
            return self.name


    class Book(models.Model):
        name = models.CharField('Book name', max_length=100)
        author = models.ForeignKey(Author, blank=True, null=True)
        author_email = models.EmailField('Author email', max_length=75, blank=True)
        imported = models.BooleanField(default=False)
        published = models.DateField('Published', blank=True, null=True)
        price = models.DecimalField(max_digits=10, decimal_places=2, null=True, blank=True)
        categories = models.ManyToManyField(Category, blank=True)

        def __str__(self):
            return self.name


.. _base-modelresource:

Creating a resource
===============================

To integrate import-export with our ``Book`` model, we will create a
:class:`~import_export.resources.ModelResource` class in ``admin.py`` that will
describe how this resource can be imported or exported::

    # app/admin.py

    from import_export import resources
    from core.models import Book

    class BookResource(resources.ModelResource):

        class Meta:
            model = Book  # or 'core.Book'

Importing data
==============

Let's import some data!

.. code-block:: python
    :linenos:
    :emphasize-lines: 4,5

    >>> import tablib
    >>> from import_export import resources
    >>> from core.models import Book
    >>> book_resource = resources.modelresource_factory(model=Book)()
    >>> dataset = tablib.Dataset(['', 'New book'], headers=['id', 'name'])
    >>> result = book_resource.import_data(dataset, dry_run=True)
    >>> print(result.has_errors())
    False
    >>> result = book_resource.import_data(dataset, dry_run=False)

In the fourth line we use :func:`~import_export.resources.modelresource_factory`
to create a default :class:`~import_export.resources.ModelResource`.
The ``ModelResource`` class created this way is equal to the one shown in the
example in section :ref:`base-modelresource`.

In fifth line a :class:`~tablib.Dataset` with columns ``id`` and ``name``, and
one book entry, are created. A field (or combination of fields) which uniquely identifies an instance always needs to
be present.  This is so that the import process can manage creates / updates.  In this case, we use ``id``.
For more information, see :ref:`advanced_usage:Create or update model instances`.

In the rest of the code we first pretend to import data using
:meth:`~import_export.resources.Resource.import_data` and ``dry_run`` set,
then check for any errors and actually import data this time.

.. seealso::

    :doc:`/import_workflow`
        for a detailed description of the import workflow and its customization options.

Deleting data
-------------

To delete objects during import, implement the
:meth:`~import_export.resources.Resource.for_delete` method on
your :class:`~import_export.resources.Resource` class.
You should add custom logic which will signify which rows are to be deleted.

For example, suppose you would like to have a field in the import dataset to indicate which rows should be deleted.
You could include a field called *delete* which has either a 1 or 0 value.

In this case, declare the resource as follows::

    class BookResource(resources.ModelResource):

        def for_delete(self, row, instance):
            return row["delete"] == "1"

        class Meta:
            model = Book

If the delete flag is set on a *'new'* instance (i.e. the row does not already exist in the db) then the row will be
skipped.

.. _exporting_data:

Exporting data
==============

Now that we have defined a :class:`~import_export.resources.ModelResource` class,
we can export books::

    >>> from core.admin import BookResource
    >>> dataset = BookResource().export()
    >>> print(dataset.csv)
    id,name,author,author_email,imported,published,price,categories
    2,Some book,1,,0,2012-12-05,8.85,1

.. warning::

    Data exported programmatically is not sanitized for malicious content.
    You will need to understand the implications of this and handle accordingly.
    See :ref:`admin_security`.