You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将kwargs从Django import_export的Resource传至自定义Widget的clean方法

问题

使用Django import_export框架时,希望将kwargs从Resource传递到自定义Widget的clean方法中。现有代码如下:

resources.py

class UserResource(ModelResource):
    identifier = Field(
        column_name="identifier",
        attribute="identifier",
        widget=RegexWidget(),
    )
    class Meta:
        model=User

widgets.py

class RegexWidget(CharWidget):
   def clean(self, value, row=None, **kwargs):
        regex = kwargs.get("regex", None)
        # 后续验证逻辑
        ...

测试时尝试以下写法,但Widget的clean方法中获取到的kwargs为空字典:

UserResource.import_data(dataset, regex=r"U\{4}d\Z")

请问该如何实现需求?

解决方案

方法一:通过Resource实例传递参数

框架默认不会将import_data的参数传递到Widget的clean方法,因此需要通过Resource实例保存参数并传递给Widget:

  1. 修改UserResource,添加初始化方法接收并传递regex参数:
class UserResource(ModelResource):
    identifier = Field(
        column_name="identifier",
        attribute="identifier",
        widget=RegexWidget(),
    )

    def __init__(self, regex=None, **kwargs):
        super().__init__(**kwargs)
        self.regex = regex
        # 将regex传递给identifier字段的widget
        self.fields['identifier'].widget.regex = regex

    class Meta:
        model=User
  1. 调整RegexWidget,直接使用实例属性获取regex:
class RegexWidget(CharWidget):
    def __init__(self, regex=None, **kwargs):
        super().__init__(**kwargs)
        self.regex = regex

    def clean(self, value, row=None, **kwargs):
        regex = self.regex
        if regex:
            # 执行正则验证逻辑,示例:
            import re
            if not re.fullmatch(regex, value):
                raise ValueError(f"值不符合正则规则:{regex}")
        # 调用父类clean方法处理基础逻辑
        return super().clean(value, row, **kwargs)
  1. 调用时先实例化Resource再执行import_data:
resource = UserResource(regex=r"U\{4}d\Z")
resource.import_data(dataset)

方法二:重写Resource的clean方法传递参数

如果不想修改Widget的初始化逻辑,可以在Resource的clean方法中主动传递参数给Widget:

  1. 修改UserResource,添加regex属性并重写clean方法:
class UserResource(ModelResource):
    identifier = Field(
        column_name="identifier",
        attribute="identifier",
        widget=RegexWidget(),
    )

    def __init__(self, regex=None, **kwargs):
        super().__init__(**kwargs)
        self.regex = regex

    def clean(self, row, instance=None, **kwargs):
        # 先执行父类clean逻辑
        row = super().clean(row, instance, **kwargs)
        # 针对identifier字段,调用widget的clean并传递regex参数
        if 'identifier' in row:
            row['identifier'] = self.fields['identifier'].widget.clean(
                row['identifier'],
                row,
                regex=self.regex
            )
        return row

    class Meta:
        model=User
  1. 调用方式同方法一:
resource = UserResource(regex=r"U\{4}d\Z")
resource.import_data(dataset)

关键说明

直接调用UserResource.import_data()是类方法,框架不会将额外参数传递到Widget的clean流程中。必须通过实例化Resource并保存参数,再通过实例调用import_data,才能让Widget获取到所需参数。

内容的提问来源于stack exchange,提问作者malik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 10:26:16