Django-import-export - import of advanced fields?
Asked Answered
I

2

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.

Intrastate answered 2/11, 2013 at 23:32 Comment(0)
S
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.

Supplement answered 6/11, 2013 at 12:33 Comment(2)
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 ..Intrastate
I asked similar question #22655839 Maybe you can help with your experience with django-import-export?Ataman
L
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!

Lennie answered 31/3, 2020 at 22:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.