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 = ""
Теперь, когда я пытаюсь выполнить импорт из файла, я получаю эту ошибку:
Мне нужно иметь возможность сделать метод 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
, очевидно, будет выполнено обновление вместо создания.
Вы уже пробовали?