Skip to content

Commit bbea055

Browse files
Update 'Creating non-existent relations' documentation (#2029)
* fixed broken link * reformatted * updated link
1 parent 86459db commit bbea055

File tree

2 files changed

+25
-13
lines changed

2 files changed

+25
-13
lines changed

docs/advanced_usage.rst

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ table using the field value will return exactly one result.
440440
This is implemented as a ``Model.objects.get()`` query, so if the instance in not uniquely identifiable based on the
441441
given arg, then the import process will raise either ``DoesNotExist`` or ``MultipleObjectsReturned`` errors.
442442

443-
See also :ref:`advanced_usage:Creating non existent relations`.
443+
See also :ref:`creating-non-existent-relations`.
444444

445445
Refer to the :class:`~.ForeignKeyWidget` documentation for more detailed information.
446446

@@ -477,26 +477,38 @@ declaration.
477477
class Meta:
478478
model = Book
479479

480-
Creating non existent relations
480+
.. _creating-non-existent-relations:
481+
482+
Creating non-existent relations
481483
-------------------------------
482484

483485
The examples above rely on the relation data being present prior to the import. It is a common use-case to create the
484-
data if it does not already exist. It is possible to achieve this as follows::
486+
data if it does not already exist. A simple way to achieve this is to override the ``ForeignKeyWidget``
487+
:meth:`~import_export.widgets.ForeignKeyWidget.clean` method::
488+
489+
class AuthorForeignKeyWidget(ForeignKeyWidget):
490+
def clean(self, value, row=None, **kwargs):
491+
try:
492+
val = super().clean(value)
493+
except Author.DoesNotExist:
494+
val = Author.objects.create(name=row['author'])
495+
return val
496+
497+
Now you will need to declare the widget in the Resource::
485498

486499
class BookResource(resources.ModelResource):
487500

488-
def before_import_row(self, row, **kwargs):
489-
author_name = row["author"]
490-
Author.objects.get_or_create(name=author_name, defaults={"name": author_name})
501+
author = fields.Field(
502+
attribute="author",
503+
column_name="author",
504+
widget=AuthorForeignKeyWidget(Author, "name")
505+
)
491506

492507
class Meta:
493508
model = Book
494509

495-
The code above can be adapted to handle m2m relationships.
496-
497-
You can also achieve similar by subclassing the widget :meth:`~import_export.widgets.ForeignKeyWidget.clean` method to
498-
create the object if it does not already exist. An example for :class:`~import_export.widgets.ManyToManyWidget` is
499-
`here <https://github.com/django-import-export/django-import-export/issues/318#issuecomment-861813245>`_.
510+
The code above can be adapted to handle m2m relationships, see
511+
`this thread <https://github.com/django-import-export/django-import-export/issues/318#issuecomment-861813245>`_.
500512

501513
Customize relation lookup
502514
-------------------------
@@ -537,7 +549,7 @@ Then if the import was being called from another module, we would pass the ``pub
537549

538550
>>> resource = BookResource(publisher_id=1)
539551

540-
If you need to pass dynamic values to the Resource from an `Admin integration`_, refer to
552+
If you need to pass dynamic values to the Resource when importing via the Admin UI, refer to
541553
See :ref:`dynamically_set_resource_values`.
542554

543555
Django Natural Keys

docs/faq.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ See `this issue <https://github.com/django-import-export/django-import-export/is
182182
How to create relation during import if it does not exist
183183
---------------------------------------------------------
184184

185-
See :ref:`advanced_usage:Creating non existent relations`.
185+
See :ref:`creating-non-existent-relations`.
186186

187187
How to handle large file uploads
188188
---------------------------------

0 commit comments

Comments
 (0)