【问题标题】:django import-export adding an emailValidator adds a new field on exportdjango import-export 添加一个 emailValidator 在导出时添加一个新字段
【发布时间】:2021-12-31 14:41:42
【问题描述】:

我有这些模型:

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,则导出的字段是预期的,但在导入时,电子邮件不会得到验证。我需要能够导出必要的字段,同时仍然能够在导入时验证它们。有谁知道我是否遗漏了一些重要的东西?提前致谢。

【问题讨论】:

    标签: django django-import-export


    【解决方案1】:

    我猜这是因为您定义了一个名为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
            # ...
    

    this thread 中的更多信息。

    【讨论】:

      猜你喜欢
      • 2015-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 2012-11-01
      • 2022-08-04
      • 1970-01-01
      • 2018-05-25
      相关资源
      最近更新 更多