Package: django-model-import
django-model-importDjango Model Import is a light weight CSV importer built for speed.It uses a standard DjangoModelFormto parse each row, giving you a familiar API to work with
for data validation and model instantiation. In most cases, if you already have aModelFormfor theContentTypeyou are importing you do not need to create an import specific form.To present feedback to the end-user running the import you can easily generate a preview
of the imported data by toggling thecommitparameter.It also provides some import optimized fields for ForeignKey's, allowing preloading all
possible values, or caching each lookup as it occurs, or looking up a model where multiple
fields are needed to uniquely identify a resource.Installationpoetryadddjango-model-importQuickstartimportdjangomodelimportclassBookImporter(djangomodelimport.ImporterModelForm):name=forms.CharField()author=CachedChoiceField(queryset=Author.objects.all(),to_field='name')classMeta:model=Bookfields=('name','author',)withdefault_storage.open('books.csv','rb')asfh:data=fh.read().decode("utf-8")# Use tablibparser=djangomodelimport.TablibCSVImportParser(BookImporter)headers,rows=parser.parse(data)# Processimporter=djangomodelimport.ModelImporter(BookImporter)preview=importer.process(headers,rows,commit=False)errors=preview.get_errors()iferrors:print(errors)importresult=importer.process(headers,rows,commit=True)forresultinimportresult.get_results():print(result.instance)Composite key lookupsOften a relationship cannot be referenced via a single unique string. For this we can use
aCachedChoiceFieldwith aCompositeLookupWidget. The widget looks for the values
under thetypeandvariantcolumns in the source CSV, and does a unique lookup
with the field names specified into_field, e.g.queryset.get(type__name=type, name=variant).The results of eachgetare cached internally for the remainder of the import minimising
any database access.classAssetImporter(ImporterModelForm):site=djangomodelimport.CachedChoiceField(queryset=Site.objects.active(),to_field='ref')type=djangomodelimport.CachedChoiceField(queryset=AssetType.objects.filter(is_active=True),to_field='name')type_variant=djangomodelimport.CachedChoiceField(queryset=InspectionItemTypeVariant.objects.filter(is_active=True),required=False,widget=djangomodelimport.CompositeLookupWidget(source=('type','variant')),to_field=('type__name','name'),)contractor=djangomodelimport.CachedChoiceField(queryset=Contractor.objects.active(),to_field='name')Flat related fieldsOften you'll have a OneToOneField or just a ForeignKey to another model, but you want to be able to
create/update that other model via this one. You can flatten all of the related model's fields onto
this importer usingFlatRelatedField.classClientImporter(ImporterModelForm):primary_contact=FlatRelatedField(queryset=ContactDetails.objects.all(),fields={'contact_name':{'to_field':'name','required':True},'email':{'to_field':'email'},'email_cc':{'to_field':'email_cc'},'mobile':{'to_field':'mobile'},'phone_bh':{'to_field':'phone_bh'},'phone_ah':{'to_field':'phone_ah'},'fax':{'to_field':'fax'},},)classMeta:model=Clientfields=('name','ref','is_active','account','primary_contact',)TestsRun tests withpython example/manage.py test testapp