not able to use import option from django-import-export

Hi Team,

I am looking for a little help, I am trying to use the django-import-export library. I already have installed version 4.3.9

I am trying to use the import option of this library to import data on model below:

class Competency_Setor_Area(SoftDelete):
    comp_sect_id = models.AutoField(primary_key=True, null=False, blank=False)
    competency = models.ForeignKey(Competency, on_delete=models.PROTECT)
    factory = models.ForeignKey(Factory, on_delete=models.PROTECT, null=True, blank=True)
    sector = models.ForeignKey(Sector, on_delete=models.PROTECT, null=True, blank=True)
    area = models.ForeignKey(Area, on_delete=models.PROTECT, null=True, blank=True)
    i_percentage = models.SmallIntegerField(null=True, blank=True)
    l_percentage = models.SmallIntegerField(null=True, blank=True)
    u_percentage = models.SmallIntegerField(null=True, blank=True)
    created_dt = models.DateField(auto_now_add=True, null=False, blank=False)
    created_by = models.ForeignKey("users.Person", on_delete=models.PROTECT, null=False, blank=False, related_name='c_comp_sect')
    last_modify_dt = models.DateField(auto_now=True, null=False, blank=False)
    last_modify_by = models.ForeignKey("users.Person", on_delete=models.PROTECT, null=False, blank=False, related_name='m_comp_sect')
    not_apply = models.BooleanField(default=False, null=False, blank=False)

    def combined_names(self):
        return f"{self.factory.factory_name} - {self.sector.sector_name} - {self.area.area_name} - {self.competency.competency_name}"

    class Meta:
        constraints = [
            UniqueConstraint(fields=['factory', 'sector', 'area', 'competency'], name='unique_fa_se_ar_competency')
        ]

    def __str__(self) -> str:
        return f"{self.factory} - {self.sector} - {self.area} - {self.competency}"
    

On my admin.py I have added the following:

from import_export.widgets import ForeignKeyWidget
from import_export.admin import ImportExportModelAdmin
from import_export import fields as import_export_fields

class competencySetorResource(resources.ModelResource):
    class Meta:
        model = Competency_Setor_Area
        import_id_field = 'comp_sect_id'
        fields = (
            'is_active', 'comp_sect_id', 'competency', 'factory', 'sector', 'area',
            'i_percentage', 'l_percentage', 'u_percentage',
            'created_by', 'last_modify_by', 'not_apply'
        )


@admin.register(Competency_Setor_Area)
class CompetencySetorAreaAdmin(ImportExportModelAdmin, admin.ModelAdmin):
    resource_class = competencySetorResource
    list_display = ('comp_sect_id', 'competency', 'factory', 'sector', 'area', 'not_apply', 'is_active')
    list_filter = ('is_active', 'competency', 'factory', 'sector', 'area', 'not_apply')
    search_fields = ('competency', 'factory', 'sector', 'area', 'not_apply',)
    actions = ['restore_selected', 'inactivate_records']

    def restore_selected(modelAdmin, request, queryset):
        queryset.update(is_active=True)

    def inactivate_records(modelAdmin, request, queryset):
        queryset.update(is_active=False)

    def has_delete_permission(self, request, obj=None):
        return True
    
    def save_model(self, request, obj, form, change):
        if not change:
            obj.created_by = request.user
            obj.last_modify_by = request.user

        else:
            obj.last_modify_by = request.user

        return super().save_model(request, obj, form, change)
    
    restore_selected.short_description = 'Activate selected Records'
    inactivate_records.short_description = 'Inactivate selected Records'

    exclude = ['created_by', 'last_modify_by']

and on settings.py I also have already included on my Installed Apps:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'import_export',
    'users',
    'platecPlus',
]

to try to avoid do any error creating the csv file to import data, I downloaded a csv by clicking on export option on the admin section. the I just updated data to be imported on that file,

this is an image how looks like my csv file

Since I am trying to insert data and the primary key comp_sect_id is auto numeric field, I left it in blank, but I also try it by entering the next consecutive number;

but the issue I get everyting I tried to import is:

Errors

  • Line number: 1 - ‘id’

  • Line number: 2 - ‘id’

I tried with different soluction on the resource class including the below code, but did not work either.

from import_export import resources
from import_export.widgets import ForeignKeyWidget
from import_export import fields as import_export_fields

from .models import Competency_Setor_Area, Competency, Factory, Sector, Area
from users.models import Person

class competencySetorResource(resources.ModelResource):

    competency = import_export_fields.Field(
        column_name='competency',
        attribute='competency',
        widget=ForeignKeyWidget(Competency, 'competency_name')
    )

    factory = import_export_fields.Field(
        column_name='factory',
        attribute='factory',
        widget=ForeignKeyWidget(Factory, 'factory_name')
    )

    sector = import_export_fields.Field(
        column_name='sector',
        attribute='sector',
        widget=ForeignKeyWidget(Sector, 'sector_name')
    )

    area = import_export_fields.Field(
        column_name='area',
        attribute='area',
        widget=ForeignKeyWidget(Area, 'area_name')
    )

    created_by = import_export_fields.Field(
        column_name='created_by',
        attribute='created_by',
        widget=ForeignKeyWidget(Person, 'username')
    )

    last_modify_by = import_export_fields.Field(
        column_name='last_modify_by',
        attribute='last_modify_by',
        widget=ForeignKeyWidget(Person, 'username')
    )

    class Meta:
        model = Competency_Setor_Area
        import_id_field = 'comp_sect_id'
        fields = (
            'is_active', 'comp_sect_id', 'competency', 'factory', 'sector', 'area',
            'i_percentage', 'l_percentage', 'u_percentage', 'created_dt',
            'created_by', 'last_modify_by', 'not_apply'
        )

any advise, would be really appreciated.

thanks

i haven’t used this, but looking at the docs, you have this in your Admin class:

import_id_field = 'comp_sect_id'

When it should be:

import_id_fields = ('comp_sect_id',)

See Advanced usage — django-import-export 4.3.10.dev1 documentation

1 Like

Hi @philgyford

Sorry for late response… It worked, thanks a lot.

Indeed, I have tried

import_id_fields = ('comp_sect_id')

but missing the comma. I fixed exactly how you mentioned and it worked; you helped me to save a lot of time input data.

An easy error to make when the tuple only has one item.

I just learned that it’s the commas, not the parentheses, that make something a tuple. From the Python docs:

Note that it is actually the comma which makes a tuple, not the parentheses. The parentheses are optional, except in the empty tuple case, or when they are needed to avoid syntactic ambiguity.