Search code examples
django-import-export

How to provide the "result.has_errors()" and "result.has_validation_errors()" attributes when using import_data method for Django import_export


I need to make changes to a csv file being imported using the module import_Export for Django. I implement the import_data method for this but get the error 'Dataset' object has no attribute 'has_errors'

    Traceback (most recent call last):
  File "C:\Program Files\Python36\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "C:\Program Files\Python36\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "C:\Program Files\Python36\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Program Files\Python36\lib\site-packages\django\utils\decorators.py", line 130, in _wrapped_view
    response = view_func(request, *args, **kwargs)
  File "C:\Program Files\Python36\lib\site-packages\django\views\decorators\cache.py", line 44, in _wrapped_view_func
    response = view_func(request, *args, **kwargs)
  File "C:\Program Files\Python36\lib\site-packages\django\contrib\admin\sites.py", line 231, in inner
    return view(request, *args, **kwargs)
  File "C:\Program Files\Python36\lib\site-packages\import_export\admin.py", line 316, in import_action
    if not result.has_errors() and not result.has_validation_errors():

Exception Type: AttributeError at /admin/engine/mtg/import/
Exception Value: 'Dataset' object has no attribute 'has_errors'

How can I provide the result.has_error() and result.has_validation_errors() when I return my customized dataset to avoid this error? Here is where I implement the method

Admin

    class ModelResource(resources.ModelResource):

    def import_data(self, dataset, dry_run=False, raise_errors=True,use_transactions=None, collect_failed_rows=False, **kwargs):
        new_dataset = do_stuff(dataset)
        return new_dataset

The documentation states that the first thing that the import_data method does is create a "result" instance containing error information. I'm assuming this is what I need maybe? But I don't know how to gain access to it or return it with my new dataset[Import Data workflow][1]

[1]: https://django-import-export.readthedocs.io/en/latest/import_workflow.html?highlight=before)import


Solution

  • You shouldn't need to override has_errors() and has_validation_errors() because the logic should be handled for you.

    Generally you shouldn't be over-riding import_data() because this is where the import logic happens. Pass a valid Dataset object into import_data() as the first arg. I suggest having a quick look at the source, because this will clarify what is going on.

    If you need to modify the imported data, then there are several hooks you can use. This is where you subclass the base Resource and add your own logic.

    This example is based on the django-import-export example app:

    class BookResource(resources.ModelResource):
        
        def before_import_row(self, row, row_number=None, **kwargs):
            """
            Override to add additional logic.
            """
            pass
    
        def before_save_instance(self, instance, using_transactions, dry_run):
            """
            Override to add additional logic.
            """
            pass
    
        class Meta:
            model = Book
            fields = ('id', 'author_email', 'price')
    

    Then you can call this with:

        rows = [
            ('book1', 'email@example.com', '10.25'),
            ('book2', 'email@example.com', '10.25'),
            ('book1', 'email@example.com', '10.25'),
        ]
        dataset = tablib.Dataset(*rows, headers=['name', 'author_email', 'price'])
    
        book_resource = BookResource()
        result = book_resource.import_data(dataset)
        print(result.totals)