B_MoSsen
B_MoSsen

Reputation: 51

Django import export, get() returned more than one

Please help me to find a solution to this error, whene using django-import-export here is my code :

Models :

class ChartOfAccounts(models.Model):
code = models.CharField('code plan comptable', max_length=20, unique=True)
name = models.CharField('plan comptable', max_length=100)

def __str__(self):
    return self.code


class Company(models.Model):
    code = models.CharField('code société', max_length=20, unique=True)
    name = models.CharField('société', max_length=100)
    addr = models.CharField('adresse', max_length=100, blank=True, null=True)
    chart_of_accounts = models.ForeignKey(ChartOfAccounts, on_delete=models.CASCADE, verbose_name='code plan comptable')
    
    def __str__(self):
    return self.code


class GLAccount(models.Model):
    class Meta:
        unique_together = (('code', 'chart_of_accounts'),)

    code = models.CharField('code compte comptable', max_length=10)
    chart_of_accounts = models.ForeignKey(ChartOfAccounts, on_delete=models.CASCADE, verbose_name='code plan comptable')
    name = models.CharField('compte comptable', max_length=100, help_text='text descriptif du compte comptable')
    
    def __str__(self):
        return f'{self.code}, {self.chart_of_accounts}'


class CompanyAccount(models.Model):
    company = models.ForeignKey(Company, verbose_name='code société', on_delete=models.CASCADE)
    gl_account = models.ForeignKey(GLAccount, verbose_name='compte comptable', on_delete=models.CASCADE)

Resources :

class CompanyAccountResource(ModelResource):
    class Meta:
        model = models.CompanyAccount
        fields = ('company', 'gl_account',)
        exclude = ('id',)
        import_id_fields = ('company', 'gl_account',)
        skip_unchanged = False
        report_skipped = False

    # fields
    company = Field(
        column_name=Meta.model._meta.get_field('company').verbose_name,
        attribute='company',
        widget=ForeignKeyWidget(models.Company, field='code')
    )
    gl_account = Field(
        column_name=Meta.model._meta.get_field('gl_account').verbose_name,
        attribute='gl_account',
        widget=ForeignKeyWidget(models.GLAccount, field='code')
    )

    def get_export_order(self):
        export_fields = ['company', 'gl_account', ]
        return export_fields

My data is :

Company model data here

ChatOfAccounts model data here

GLAccount model data here

CompanyAccountResource Excel canvas to import data

the problem :

a GLAccount code may apear in 2 chart of accounts, each related to one company, and when try to import data from excel to CompanyAccountResource, the error below will apear :

    Line number: 1 - get() returned more than one GLAccount -- it returned 2!
S001, 600000
Traceback (most recent call last):
File "C:\Users\Leo\PycharmProjects\Django\DjangoSnippets\venv\lib\site-packages\import_export\resources.py", line 639, in import_row
instance, new = self.get_or_init_instance(instance_loader, row)
File "C:\Users\Leo\PycharmProjects\Django\DjangoSnippets\venv\lib\site-packages\import_export\resources.py", line 334, in get_or_init_instance
instance = self.get_instance(instance_loader, row)
File "C:\Users\Leo\PycharmProjects\Django\DjangoSnippets\venv\lib\site-packages\import_export\resources.py", line 327, in get_instance
return instance_loader.get_instance(row)
File "C:\Users\Leo\PycharmProjects\Django\DjangoSnippets\venv\lib\site-packages\import_export\instance_loaders.py", line 29, in get_instance
params[field.attribute] = field.clean(row)
File "C:\Users\Leo\PycharmProjects\Django\DjangoSnippets\venv\lib\site-packages\import_export\fields.py", line 66, in clean
value = self.widget.clean(value, row=data)
File "C:\Users\Leo\PycharmProjects\Django\DjangoSnippets\venv\lib\site-packages\import_export\widgets.py", line 396, in clean
return self.get_queryset(value, row, *args, **kwargs).get(**{self.field: val})
File "C:\Users\Leo\PycharmProjects\Django\DjangoSnippets\venv\lib\site-packages\django\db\models\query.py", line 433, in get
raise self.model.MultipleObjectsReturned(
app1.models.GLAccount.MultipleObjectsReturned: get() returned more than one GLAccount -- it returned 2!

Upvotes: 2

Views: 808

Answers (1)

Matthew Hegarty
Matthew Hegarty

Reputation: 4306

The error is occurring because you are defining import_id_fields which don't uniquely identify an object.

import_id_fields is used by the import workflow to identify an existing model instance for update. In your case, the combination of 'company', 'gl_account' is identifying multiple rows in the CompanyAccountResource.

If you need your import logic to update existing instances, then you will have to find a way to uniquely identify the row for update.

Upvotes: 1

Related Questions