Django import-export добавление emailValidator добавляет новое поле при экспорте

У меня есть эти модели:

Investment
Profile

где Investment имеет внешний ключ к Profile через электронную почту. Я пытаюсь выполнить массовый экспорт, но при экспорте добавляется дубликат profile__email без каких-либо значений.

Результат выборки:

enter image description here

Я заметил, что это из-за добавленного валидатора в моем 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
        # ...

Больше информации в этой теме.

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