12

For a Django model I'm using django-import-export package.

If need to export more then just available model fields, like properties or custom fields, new can be added with import_export.fields.Field class and optionally dehydrate_<field> method.

from import_export import resources, fields, instance_loaders

class ProductResource(resources.ModelResource):
    categories  = fields.Field()
    price       = fields.Field(attribute='unit_price')

    class Meta:
        model  = Product

    def dehydrate_categories(self, product):
        return ';'.join(
                '/%s' % '/'.join([c.name for c in cat.parents()] + [cat.name])
                for cat in product.category.iterator() )

It does work well, but only for exporting. What about import, the reverse process ? Is there some counterpart to dehydrate_ method ?

So far I've overridden get_or_init_instance method:

class ProductResource(resources.ModelResource):
    def get_or_init_instance(self, instance_loader, row):
        row['unit_price'] = row['price']; row.pop('price')
        return super(ProductResource, self).get_or_init_instance(instance_loader, row)

but doubt this is the right way.

Would appreciate any hint how to handle imports of custom fields.

Zulu
  • 8,765
  • 9
  • 49
  • 56
David Unric
  • 7,421
  • 1
  • 37
  • 65

2 Answers2

5

You can override import_obj instead. See Import workflow for more details.

Another approach is to subclass Field and override export and save methods and do all required data manipulation in a field.

bmihelac
  • 6,233
  • 34
  • 45
  • Thanks. Sure, overriding Field methods is a good idea but I've been just interested if there is already some way how to import custom field contents previously exported with `dehydrate_` methods. Don't like to reinvent a wheel .. – David Unric Nov 07 '13 at 14:11
  • I asked similar question http://stackoverflow.com/questions/22655339/django-admin-import-export-module-used-for-custom-import Maybe you can help with your experience with django-import-export? – andilabs Mar 26 '14 at 08:38
1

I know this is very old but I came across the same problem and this is how I fixed it (based on the direction the original asker was heading). First, you can add any custom/modified fields you need by overriding the 'before_import_row' function, like so:

    def before_import_row(self, row, **kwargs):
        row['extra_info'] = 'Some Info'
        return super(RetailLocationResource, self).before_import_row(row, **kwargs)

Then you can pass this into your instance by overriding get_or_init_instance like so:

    def get_or_init_instance(self, instance_loader, row):
        instance, bool = super(RetailLocationResource, self).get_or_init_instance(instance_loader, row)
        instance.extra_info = row['extra_info']
        return instance, bool

Hope this helps anyone!

npwhite
  • 36
  • 4