Django-import-export не обновляется при уникализации

У меня это unique field на моем Profile model:

email = models.EmailField(max_length=200, unique=True)

и у меня есть это ProfileResource:

class ProfileResource(resources.ModelResource):

    # associated_issuer = fields.Field(attribute='add_associated_issuer', widget=ManyToManyWidget(Issuer, field='name'), column_name='Associated Issuer')
    email = fields.Field(attribute='email', 
        widget=CharWidget(), 
        column_name='email')

    class Meta:
        model = Profile
        clean_model_instances = True
        import_id_fields = ('id', 'email')

    def before_import_row(self, row, row_number=None, **kwargs):
        try:
            self.email = row["email"] 
        except Exception as e:
            self.email = ""

        try:
            if row["id"] == '':
                row["id"] = None
                self.id = row["id"] 
        except Exception as e:
            self.id = None

        try:
           self.firstname = row["firstname"] 
        except Exception as e:
            self.firstname = ""

        try:
           self.lastname = row["lastname"]
        except Exception as e:
            self.lastname = ""

Теперь, когда я пытаюсь выполнить импорт из файла, я получаю эту ошибку:

enter image description here

Мне нужно иметь возможность сделать метод update_or_create, но куда мне добавить этот код? Я пытался сделать это на after_import_instance, но это не сработало.

Я также попробовал на import_row вот так:

def import_row(self, row, instance_loader, using_transactions=True, dry_run=False, **kwargs):
    try:
        Profile.objects.update_or_create(email=self.email)
    except Exception as e:
        print(e, file=sys.stderr)

но он выдал эту ошибку:

Exception Value: 'NoneType' object has no attribute 'import_type'

Любые соображения по поводу исправления были бы признательны.

#try this 

email = models.EmailField(max_length=200, unique=True, null=True)

        try:
            self.email = row["email"] 
        except Exception as e:
            self.email = None

unique=True также блокирует дублирование "", но null не блокируется.

Обратите внимание, что у вас есть эта строка на ProfileResource

import_id_fields = ('id', 'email')

Это означает, что импорт будет просматривать каждую строку в вашем файле импорта и пытаться загрузить все экземпляры Profile, которые соответствуют и id, и email.

<<<Поэтому, если вам нужно обновить только

, то просто удалите это из списка email. Таким образом, логика будет однозначно идентифицировать экземпляры, основываясь только на import_id_fields, а затем будут созданы новые записи, если они не существуют, и все существующие записи будут обновлены (что будет включать обновление адреса электронной почты).id

Так должно работать import-export, и никакой дальнейшей логики не требуется.

Если email является "уникальным полем", которое соответствует существующим экземплярам, то это должно быть единственное поле в import_id_fields. Не может быть двух экземпляров Profile с одинаковым email, потому что unique=True, поэтому вы можете использовать email в качестве import_id_field. Однако невозможно будет обновить электронную почту Profile с помощью import-export (хотя вы можете ввести поле new_email и иметь логику для обновления Profile таким образом, но это отдельная тема).

Я не знаю, почему вы видите ошибку 'email уже существует' - возможно, происходит что-то другое, и это может быть логика в before_import_row(), которая вызывает проблему, возможно, из-за того, что создается строка с пустой строкой в качестве email.

btw - вам не нужна логика в before_import_row() - import-export должен обрабатывать это за вас, а переопределение может внести дополнительные ошибки.

Лучший совет по использованию import-export - установить точки останова в вашей IDE, а затем выполнить шаг во время импорта, и вы сможете увидеть, что именно происходит. Это сэкономит вам много времени в долгосрочной перспективе.

В итоге, используйте либо id либо email в import_id_fields и это должно сработать.

Вам следует попытаться измениться

import_id_fields = ('id', 'email')

by

import_id_fields = ('email',)

Когда вы пытаетесь импортировать ряд с пустым ID, он всегда будет восприниматься как новый ряд. Поэтому в этом случае выполняется создание, а не обновление. Но когда вы оставляете только email в вашем import_id_fields, очевидно, будет выполнено обновление вместо создания.

Вы уже пробовали?

Вернуться на верх