Django import-export добавление emailValidator добавляет новое поле при экспорте
У меня есть эти модели:
Investment
Profile
где Investment
имеет внешний ключ к Profile
через электронную почту. Я пытаюсь выполнить массовый экспорт, но при экспорте добавляется дубликат profile__email
без каких-либо значений.
Результат выборки:
Я заметил, что это из-за добавленного валидатора в моем InvestmentResource
:
class InvestmentResource(resources.ModelResource):
class ValidatingEmailForeignKeyWidget(ForeignKeyWidget):
def clean(self, value, row=None, *args, **kwargs):
try:
validate_email(value)
except ValidationError as e:
# a quirk of import-export means that the ValidationError
# should be re-raised
raise ValueError(f"invalid email {e}")
try:
val = super().clean(value)
return value
except self.model.DoesNotExist:
raise ValueError(f"{self.model.__name__} with value={value} does not exist")
email = fields.Field(attribute='profile__email',
widget=ValidatingEmailForeignKeyWidget(Profile, field='email'),
column_name='profile__email')
class Meta:
model = Investment
clean_model_instances = True
import_id_fields = ('id',)
fields = (
'id',
'notes',
'firstname',
'lastname',
'email',)
export_order = fields
def before_import_row(self, row, row_number=None, **kwargs):
self.profile__email = row["profile__email"]
self.profile__firstname = row["firstname"]
self.profile__lastname = row["lastname"]
def after_import_instance(self, instance, new, row_number=None, **kwargs):
"""
Create any missing Profile entries prior to importing rows.
"""
try:
# print(self.isEmailValid(self.email), file=sys.stderr)
profile, created = Profile.objects.get_or_create(email=self.profile__email)
profile.firstname = self.profile__firstname
profile.lastname = self.profile__lastname
profile.save()
instance.profile = profile
except Exception as e:
print(e, file=sys.stderr)
Если я пытаюсь удалить валидатор и изменить email
в полях на profile__email
, экспортируемые поля соответствуют ожидаемым, но при импорте электронные письма не проходят валидацию. Мне нужно иметь возможность экспортировать необходимые поля и при этом проверять их при импорте. Кто-нибудь знает, может быть, я упускаю что-то важное? Заранее спасибо.
Мое предположение, что это происходит потому, что вы определяете атрибут под названием profile__email
:
def before_import_row(self, row, row_number=None, **kwargs):
self.profile__email = row["profile__email"]
Вам не нужно этого делать, потому что import-export
должен определить, что это поле для импорта, если оно указано в csv. Я думаю, если вы удалите эту строку, все будет работать.
Однако, если вы хотите больше контроля над тем, какие поля появляются в экспорте, вы можете переопределить get_export_order()
, чтобы вернуть итерабельную таблицу, содержащую только те поля, которые вам нужны, например, это экспортирует только поле 'id'.
class InvestmentResource(resources.ModelResource):
def get_export_order(self):
return (
'id',
'notes',
'firstname',
'lastname',
'email'
)
class Meta:
model = Investment
# ...
Больше информации в этой теме.